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
