Commit: fb820c063831a36b9780a8948219e0eb9ff27da2
Author: Thomas Dinges
Date:   Wed Nov 5 22:48:45 2014 +0100
Branches: master
https://developer.blender.org/rBfb820c063831a36b9780a8948219e0eb9ff27da2

Cycles: Add "Max Bounce" control for lamps

With this setting, we can limit the influence of a lamp to a certain amount of 
bounces.
0 = Only direct light contribution
1 = 1 light bounce
...

Differential revision: https://developer.blender.org/D860

You can find an example render in the release logs: 
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.73/Cycles

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

M       intern/cycles/blender/addon/properties.py
M       intern/cycles/blender/addon/ui.py
M       intern/cycles/blender/blender_object.cpp
M       intern/cycles/kernel/kernel_light.h
M       intern/cycles/kernel/kernel_path_surface.h
M       intern/cycles/kernel/kernel_path_volume.h
M       intern/cycles/kernel/kernel_types.h
M       intern/cycles/render/light.cpp
M       intern/cycles/render/light.h

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

diff --git a/intern/cycles/blender/addon/properties.py 
b/intern/cycles/blender/addon/properties.py
index bd4ade0..9459b75 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -653,6 +653,12 @@ class CyclesLampSettings(bpy.types.PropertyGroup):
                 min=1, max=10000,
                 default=1,
                 )
+        cls.max_bounces = IntProperty(
+                name="Max Bounces",
+                description="Maximum number of bounces the light will 
contribute to the render",
+                min=0, max=1024,
+                default=1024,
+                )
         cls.use_multiple_importance_sampling = BoolProperty(
                 name="Multiple Importance Sample",
                 description="Use multiple importance sampling for the lamp, "
diff --git a/intern/cycles/blender/addon/ui.py 
b/intern/cycles/blender/addon/ui.py
index 6a08b47..e4f34f3 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -729,11 +729,11 @@ class CyclesLamp_PT_lamp(CyclesButtonsPanel, Panel):
 
         if cscene.progressive == 'BRANCHED_PATH':
             col.prop(clamp, "samples")
+        col.prop(clamp, "max_bounces")
 
         col = split.column()
         col.prop(clamp, "cast_shadow")
-
-        layout.prop(clamp, "use_multiple_importance_sampling")
+        col.prop(clamp, "use_multiple_importance_sampling")
 
         if lamp.type == 'HEMI':
             layout.label(text="Not supported, interpreted as sun lamp")
diff --git a/intern/cycles/blender/blender_object.cpp 
b/intern/cycles/blender/blender_object.cpp
index 1e07c5f..3a32a09 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -168,6 +168,8 @@ void BlenderSync::sync_light(BL::Object b_parent, int 
persistent_id[OBJECT_PERSI
        else
                light->samples = samples;
 
+       light->max_bounces = get_int(clamp, "max_bounces");
+
        /* visibility */
        uint visibility = object_ray_visibility(b_ob);
        light->use_diffuse = (visibility & PATH_RAY_DIFFUSE) != 0;
diff --git a/intern/cycles/kernel/kernel_light.h 
b/intern/cycles/kernel/kernel_light.h
index 659c4a1..f9ac86e 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -648,7 +648,13 @@ ccl_device int light_distribution_sample(KernelGlobals 
*kg, float randt)
 
 /* Generic Light */
 
-ccl_device void light_sample(KernelGlobals *kg, float randt, float randu, 
float randv, float time, float3 P, LightSample *ls)
+ccl_device bool light_select_reached_max_bounces(KernelGlobals *kg, int index, 
int bounce)
+{
+       float4 data4 = kernel_tex_fetch(__light_data, index*LIGHT_SIZE + 4);
+       return (bounce > __float_as_int(data4.x));
+}
+
+ccl_device void light_sample(KernelGlobals *kg, float randt, float randu, 
float randv, float time, float3 P, int bounce, LightSample *ls)
 {
        /* sample index */
        int index = light_distribution_sample(kg, randt);
@@ -670,6 +676,12 @@ ccl_device void light_sample(KernelGlobals *kg, float 
randt, float randu, float
        }
        else {
                int lamp = -prim-1;
+
+               if(UNLIKELY(light_select_reached_max_bounces(kg, lamp, 
bounce))) {
+                       ls->pdf = 0.0f;
+                       return;
+               }
+
                lamp_light_sample(kg, lamp, randu, randv, P, ls);
        }
 }
diff --git a/intern/cycles/kernel/kernel_path_surface.h 
b/intern/cycles/kernel/kernel_path_surface.h
index 9553c2d..e5ba1f4 100644
--- a/intern/cycles/kernel/kernel_path_surface.h
+++ b/intern/cycles/kernel/kernel_path_surface.h
@@ -38,6 +38,9 @@ ccl_device void 
kernel_branched_path_surface_connect_light(KernelGlobals *kg, RN
        if(sample_all_lights) {
                /* lamp sampling */
                for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) {
+                       if(UNLIKELY(light_select_reached_max_bounces(kg, i, 
state->bounce)))
+                          continue;
+
                        int num_samples = 
ceil_to_int(num_samples_adjust*light_select_num_samples(kg, i));
                        float num_samples_inv = 
num_samples_adjust/(num_samples*kernel_data.integrator.num_all_lights);
                        RNG lamp_rng = cmj_hash(*rng, i);
@@ -82,7 +85,7 @@ ccl_device void 
kernel_branched_path_surface_connect_light(KernelGlobals *kg, RN
                                        light_t = 0.5f*light_t;
 
                                LightSample ls;
-                               light_sample(kg, light_t, light_u, light_v, 
sd->time, sd->P, &ls);
+                               light_sample(kg, light_t, light_u, light_v, 
sd->time, sd->P, state->bounce, &ls);
 
                                if(direct_emission(kg, sd, &ls, &light_ray, 
&L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
                                        /* trace shadow ray */
@@ -103,7 +106,7 @@ ccl_device void 
kernel_branched_path_surface_connect_light(KernelGlobals *kg, RN
                path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, 
&light_v);
 
                LightSample ls;
-               light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, 
&ls);
+               light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, 
state->bounce, &ls);
 
                /* sample random light */
                if(direct_emission(kg, sd, &ls, &light_ray, &L_light, &is_lamp, 
state->bounce, state->transparent_bounce)) {
@@ -200,7 +203,7 @@ ccl_device_inline void 
kernel_path_surface_connect_light(KernelGlobals *kg, RNG
 #endif
 
        LightSample ls;
-       light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+       light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, 
state->bounce, &ls);
 
        if(direct_emission(kg, sd, &ls, &light_ray, &L_light, &is_lamp, 
state->bounce, state->transparent_bounce)) {
                /* trace shadow ray */
diff --git a/intern/cycles/kernel/kernel_path_volume.h 
b/intern/cycles/kernel/kernel_path_volume.h
index d814383..11d3d94 100644
--- a/intern/cycles/kernel/kernel_path_volume.h
+++ b/intern/cycles/kernel/kernel_path_volume.h
@@ -40,7 +40,7 @@ ccl_device void 
kernel_path_volume_connect_light(KernelGlobals *kg, RNG *rng,
        light_ray.time = sd->time;
 #endif
 
-       light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+       light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, 
state->bounce, &ls);
        if(ls.pdf == 0.0f)
                return;
        
@@ -124,6 +124,9 @@ ccl_device void 
kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
        if(sample_all_lights) {
                /* lamp sampling */
                for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) {
+                       if(UNLIKELY(light_select_reached_max_bounces(kg, i, 
state->bounce)))
+                               continue;
+
                        int num_samples = 
ceil_to_int(num_samples_adjust*light_select_num_samples(kg, i));
                        float num_samples_inv = 
num_samples_adjust/(num_samples*kernel_data.integrator.num_all_lights);
                        RNG lamp_rng = cmj_hash(*rng, i);
@@ -188,7 +191,7 @@ ccl_device void 
kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
                                        light_t = 0.5f*light_t;
 
                                LightSample ls;
-                               light_sample(kg, light_t, light_u, light_v, 
sd->time, ray->P, &ls);
+                               light_sample(kg, light_t, light_u, light_v, 
sd->time, ray->P, state->bounce, &ls);
 
                                float3 tp = throughput;
 
@@ -203,7 +206,7 @@ ccl_device void 
kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
                                kernel_assert(result == VOLUME_PATH_SCATTERED);
 
                                /* todo: split up light_sample so we don't have 
to call it again with new position */
-                               light_sample(kg, light_t, light_u, light_v, 
sd->time, sd->P, &ls);
+                               light_sample(kg, light_t, light_u, light_v, 
sd->time, sd->P, state->bounce, &ls);
 
                                if(ls.pdf == 0.0f)
                                        continue;
@@ -227,7 +230,7 @@ ccl_device void 
kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
                path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, 
&light_v);
 
                LightSample ls;
-               light_sample(kg, light_t, light_u, light_v, sd->time, ray->P, 
&ls);
+               light_sample(kg, light_t, light_u, light_v, sd->time, ray->P, 
state->bounce, &ls);
 
                float3 tp = throughput;
 
@@ -242,7 +245,7 @@ ccl_device void 
kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
                kernel_assert(result == VOLUME_PATH_SCATTERED);
 
                /* todo: split up light_sample so we don't have to call it 
again with new position */
-               light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, 
&ls);
+               light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, 
state->bounce, &ls);
 
                if(ls.pdf == 0.0f)
                        return;
diff --git a/intern/cycles/kernel/kernel_types.h 
b/intern/cycles/kernel/kernel_types.h
index cfac8d1..a7d269a 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -29,7 +29,7 @@ CCL_NAMESPACE_BEGIN
 /* constants */
 #define OBJECT_SIZE            11
 #define OBJECT_VECTOR_SIZE     6
-#define LIGHT_SIZE                     4
+#define LIGHT_SIZE                     5
 #define FILTER_TABLE_SIZE      256
 #define RAMP_TABLE_SIZE                256
 #define PARTICLE_SIZE          5
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index 1f00663..a129a0f 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -125,6 +125,7 @@ Light::Light()
 
        shader = 0;
        samples = 1;
+       max_bounces = 1024;
 }
 
 void Light::tag_update(Scene *scene)
@@ -489,6 +490,7 @@ void LightManager::device_update_points(Device *device, 
DeviceScene *dscene, Sce
                float3 co = light->co;
                int shader_id = 
scene->shader_manager->get_shader_id(scene->lights[i]->shader);
                float samples = __int_as_float(light->samples);
+               float max_bounces = __int_as_float(light->max_bounces);
 
                if(!light->cast_shadow)
                        shader_id &= ~SHADER_CAST_SHADOW;
@@ -523,6 +525,7 @@ void LightManager::device_update_points(Device *device, 
DeviceScene *dscene, Sce
                        light_data[i*LIGHT_SIZE + 1] = 
make_float4(__int_as_float(shader_id), radius, invarea, 0.0f);
                        light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 
0.0f, 0.0f);
                        light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 
0.0f, 0.0f, 0.0f);
+                       light_data[i*LIGHT_SIZE + 4] = make_float4(max_bounces, 
0.0f, 0.0f, 0.0f);
                }
                else if(light->type == LIGHT_DISTANT) {
                        shader_id &= ~SHADER_AREA_LIGHT;
@@ -544,6 +547,7 @@ void LightManager::device_update_points(Device *device, 
DeviceScene *dscene, Sce
                        light_data[i*LIGHT_SIZE + 1] = 
make_float4(__int_as_float(shader_id), radius, cosangle, invarea);
                        light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 
0.0f, 0.0f);
                        light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 
0.0f, 0.0f, 0.0f);
+                       light_data[i*LIGHT_SIZE + 4] = make_float4(max_bounces, 
0.0f, 0.0f, 0.0f);
                }
                else if(light->type == LIGHT_BACKGROUND) {
                        uint v

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to