Commit: 36cfc9e9fdc12beeec3545854bb2ccbb23ef17c6
Author: Erik Englesson
Date:   Tue Jul 3 10:36:58 2018 +0200
Branches: gsoc-2018-many-light-sampling
https://developer.blender.org/rB36cfc9e9fdc12beeec3545854bb2ccbb23ef17c6

Cycles: First iteration on split traversal

This makes it possible to sample and evaluate several
lights in a single tree traversal. Should sample highly
specular lights better too. Can only be used in branched
path tracing.

This commit contains the following:
* GUI for setting the splitting threshold
* Recursive split traversal
  - Split method based on solid angle and BSDF peak
  - At leafs the path radiance is accumulated to L
  - Have created a simplified GGX eval that is not
    currently being used.
* Refactor of common code

This is in development.

===================================================================

M       intern/cycles/blender/addon/presets.py
M       intern/cycles/blender/addon/properties.py
M       intern/cycles/blender/addon/ui.py
M       intern/cycles/blender/blender_sync.cpp
M       intern/cycles/kernel/closure/bsdf_microfacet.h
M       intern/cycles/kernel/kernel_light.h
M       intern/cycles/kernel/kernel_path_surface.h
M       intern/cycles/kernel/kernel_types.h
M       intern/cycles/render/integrator.h
M       intern/cycles/render/light.cpp

===================================================================

diff --git a/intern/cycles/blender/addon/presets.py 
b/intern/cycles/blender/addon/presets.py
index ca9edd0c600..85e075a5167 100644
--- a/intern/cycles/blender/addon/presets.py
+++ b/intern/cycles/blender/addon/presets.py
@@ -69,6 +69,7 @@ class AddPresetSampling(AddPresetBase, Operator):
         "cycles.volume_samples",
         "cycles.use_square_samples",
         "cycles.use_light_bvh",
+        "cycles.splitting_threshold",
         "cycles.progressive",
         "cycles.seed",
         "cycles.sample_clamp_direct",
diff --git a/intern/cycles/blender/addon/properties.py 
b/intern/cycles/blender/addon/properties.py
index dac9844a11c..b2df2c927e9 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -195,6 +195,13 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
                 default=False,
                 )
 
+        cls.splitting_threshold = FloatProperty(
+                name="Splitting",
+                description="Threshold for splitting. 0.0=one light, 1.0=all 
lights",
+                min=0.0, max=1.0,
+                default=0.0,
+                )
+
         cls.samples = IntProperty(
                 name="Samples",
                 description="Number of samples to render for each pixel",
diff --git a/intern/cycles/blender/addon/ui.py 
b/intern/cycles/blender/addon/ui.py
index bb1b7bee1f4..f7ceddba4a5 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -214,6 +214,10 @@ class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel):
         row = layout.row(align=True)
         row.label(text="Experimental:")
         row.prop(cscene, "use_light_bvh", text="Light BVH")
+        if cscene.use_light_bvh and use_branched_path(context):
+            row = layout.row(align=True)
+            row.label(text="") # create empty column
+            row.prop(cscene, "splitting_threshold", text="Splitting")
 
         draw_samples_info(layout, context)
 
diff --git a/intern/cycles/blender/blender_sync.cpp 
b/intern/cycles/blender/blender_sync.cpp
index 49acba9304d..74169a30f53 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -282,6 +282,7 @@ void BlenderSync::sync_integrator()
                                                          Integrator::PATH);
 
        integrator->use_light_bvh = get_boolean(cscene, "use_light_bvh");
+       integrator->splitting_threshold = get_float(cscene, 
"splitting_threshold");
        integrator->sample_all_lights_direct = get_boolean(cscene, 
"sample_all_lights_direct");
        integrator->sample_all_lights_indirect = get_boolean(cscene, 
"sample_all_lights_indirect");
        integrator->light_sampling_threshold = get_float(cscene, 
"light_sampling_threshold");
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h 
b/intern/cycles/kernel/closure/bsdf_microfacet.h
index 2dd59354058..369beee1d2c 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -391,6 +391,81 @@ ccl_device void bsdf_microfacet_ggx_blur(ShaderClosure 
*sc, float roughness)
        bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y);
 }
 
+/* TODO: Use this in the tree traversal splitting */
+ccl_device float3 bsdf_microfacet_ggx_eval_reflect_simple(const ShaderClosure 
*sc, const float3 I, const float3 omega_in)
+{
+       const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
+       float alpha_x = bsdf->alpha_x;
+       float alpha_y = bsdf->alpha_y;
+       bool m_refractive = bsdf->type == 
CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+       float3 N = bsdf->N;
+
+       if(m_refractive || alpha_x*alpha_y <= 1e-7f)
+               return make_float3(0.0f, 0.0f, 0.0f);
+
+       float cosNO = dot(N, I);
+       float cosNI = dot(N, omega_in); // pass in our conservative cosine 
instead of this one?
+                                       // fresnel calcs some kind of cosine 
with I too.
+
+       if(cosNI > 0 && cosNO > 0) {
+               /* get half vector */
+               float3 m = normalize(omega_in + I);
+               float alpha2 = alpha_x * alpha_y;
+               float D, G1o, G1i;
+
+               /* assume isotropic */
+
+               /* isotropic
+                        * eq. 20: (F*G*D)/(4*in*on)
+                        * eq. 33: first we calculate D(m) */
+               float cosThetaM = dot(N, m);
+               float cosThetaM2 = cosThetaM * cosThetaM;
+               float cosThetaM4 = cosThetaM2 * cosThetaM2;
+               float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
+
+               /* use GTR2 */
+               D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * 
(alpha2 + tanThetaM2));
+
+               /* eq. 34: now calculate G1(i,m) and G1(o,m) */
+               //G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / 
(cosNO * cosNO)));
+               //G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / 
(cosNI * cosNI)));
+
+               /* Let a2=alpha2 and cos=cosNO/cosNI then the above is 
equivalent to:
+                * 2    / (    1 + sqrt(      1 + a2 * (1 - cos^2)  / cos^2 )   
    )       = /common denom/       =
+                * 2    / (    1 + sqrt( (cos^2 + a2 * (1 - cos^2)) / cos^2 )   
    )       = /factor out 1/cos^2/ =
+                * 2    / (    1 + sqrt(  cos^2 + a2 * (1 - cos^2)          ) / 
cos )       = /common denom/       =
+                * 2    / ( (cos + sqrt(  cos^2 + a2 * (1 - cos^2)          )   
    ) / cos = /move cos to num/    =
+                * 2cos / (  cos + sqrt(  cos^2 + a2 * (1 - cos^2)          )   
    )       = /rewrite sqrt/       =
+                * 2cos / (  cos + sqrt(  cos^2 * (1 - a2) + a2             )   
    )
+                * => removes one of the divisions
+                *
+                *  - Glo should contain a cosNO in its numerator but this 
cancels with
+                *    cosNO in the denomenator in eq. 20.(removes another 
division)
+                *  - There should be a cosNI in the denomenator of eq. 20 but 
I think
+                *    this has been canceled out already since there is no 
cosNI in
+                *    path_radiance_bsdf_bounce() ?
+                *  - Both Glo and Gli should contain a 2.0 in their numerators 
but they
+                *    cancel with 1/4 in eq. 20.
+                *
+                * => This code does three less divisions in total
+                *  This could potentially be used in the real GGX evaluation 
too.
+                */
+               G1o = 1.0f  / (cosNO + safe_sqrtf(cosNO * cosNO * (1.0f - 
alpha2) + alpha2));
+               G1i = cosNI / (cosNI + safe_sqrtf(cosNI * cosNI * (1.0f - 
alpha2) + alpha2));
+
+               float G = G1o * G1i;
+
+               /* eq. 20 */
+               float3 F = reflection_color(bsdf, omega_in, m);
+
+               float3 out = F * G * D;
+
+               return out;
+       }
+
+       return make_float3(0.0f, 0.0f, 0.0f);
+}
+
 ccl_device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, 
const float3 I, const float3 omega_in, float *pdf)
 {
        const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc;
diff --git a/intern/cycles/kernel/kernel_light.h 
b/intern/cycles/kernel/kernel_light.h
index 22804c58aa8..39d575adefa 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -1122,6 +1122,7 @@ ccl_device float calc_node_importance(KernelGlobals *kg, 
float3 P, int node_offs
        float theta_u = 0; // TODO: Figure out how to calculate this one
        float d2 = len_squared(centroidToP);
 
+       // todo: fix clamp here so it is 0 outside theta_e + theta_o ?
        return energy * cosf(clamp(theta - theta_o - theta_u, 0.0, theta_e))/d2;
 }
 
@@ -1378,22 +1379,18 @@ ccl_device void light_distribution_sample(KernelGlobals 
*kg, float3 P,
        }
 }
 
-/* picks a point on a light and computes the probability of picking this 
point*/
-ccl_device_noinline bool light_sample(KernelGlobals *kg,
-                                      float randu,
-                                      float randv,
-                                      float time,
-                                      float3 P,
-                                      int bounce,
-                                      LightSample *ls)
+/* picks a point on a given light and computes the probability of picking this 
point*/
+ccl_device void light_point_sample(KernelGlobals *kg,
+                              float randu,
+                              float randv,
+                              float time,
+                              float3 P,
+                              int bounce,
+                              int distribution_id,
+                              LightSample *ls)
 {
-       /* sample index and compute light picking pdf */
-       float pdf_factor = 0.0f;
-       int index = -1;
-       light_distribution_sample(kg, P, &randu, &index, &pdf_factor);
-
        /* fetch light data and compute rest of light pdf */
-       const ccl_global KernelLightDistribution *kdistribution = 
&kernel_tex_fetch(__light_distribution, index);
+       const ccl_global KernelLightDistribution *kdistribution = 
&kernel_tex_fetch(__light_distribution, distribution_id);
        int prim = kdistribution->prim;
 
        if(prim >= 0) {
@@ -1407,13 +1404,31 @@ ccl_device_noinline bool light_sample(KernelGlobals *kg,
                int lamp = -prim-1;
 
                if(UNLIKELY(light_select_reached_max_bounces(kg, lamp, 
bounce))) {
-                       return false;
+                       ls->pdf = 0.0f;
+                       return;
                }
 
                if (!lamp_light_sample(kg, lamp, randu, randv, P, ls)){
-                       return false;
+                       ls->pdf = 0.0f;
+                       return;
                }
        }
+}
+
+/* picks a point on a light and computes the probability of picking this 
point*/
+ccl_device_noinline bool light_sample(KernelGlobals *kg,
+                                      float randu,
+                                      float randv,
+                                      float time,
+                                      float3 P,
+                                      int bounce,
+                                      LightSample *ls)
+{
+       /* sample index and compute light picking pdf */
+       float pdf_factor = 0.0f;
+       int index = -1;
+       light_distribution_sample(kg, P, &randu, &index, &pdf_factor);
+       light_point_sample(kg, randu, randv, time, P, bounce, index, ls);
 
        /* combine pdfs */
        ls->pdf *= pdf_factor;
diff --git a/intern/cycles/kernel/kernel_path_surface.h 
b/intern/cycles/kernel/kernel_path_surface.h
index f69fadb6669..54062a1c2b7 100644
--- a/intern/cycles/kernel/kernel_path_surface.h
+++ b/intern/cycles/kernel/kernel_path_surface.h
@@ -14,8 +14,238 @@
  * limitations under the License.
  */
 
+#include "util/util_logging.h"
+
 CCL_NAMESPACE_BEGIN
 
+ccl_device void accum_light_contribution(KernelGlobals *kg,
+                                         ShaderData *sd,
+                                         ShaderData* emission_sd,
+                                         LightSamp

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to