diff options
Diffstat (limited to 'intern/cycles/kernel/kernel_light.h')
-rw-r--r-- | intern/cycles/kernel/kernel_light.h | 61 |
1 files changed, 34 insertions, 27 deletions
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index 758e91159b6..ce908ce0fe2 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -1076,7 +1076,7 @@ ccl_device int light_distribution_sample(KernelGlobals *kg, float *randu) int len = kernel_data.integrator.num_distribution + 1; float r = *randu; - while (len > 0) { + do { int half_len = len >> 1; int middle = first + half_len; @@ -1087,7 +1087,7 @@ ccl_device int light_distribution_sample(KernelGlobals *kg, float *randu) first = middle + 1; len = len - half_len - 1; } - } + } while (len > 0); /* Clamping should not be needed but float rounding errors seem to * make this fail on rare occasions. */ @@ -1104,42 +1104,49 @@ ccl_device int light_distribution_sample(KernelGlobals *kg, float *randu) /* Generic Light */ -ccl_device bool light_select_reached_max_bounces(KernelGlobals *kg, int index, int bounce) +ccl_device_inline bool light_select_reached_max_bounces(KernelGlobals *kg, int index, int bounce) { return (bounce > kernel_tex_fetch(__lights, index).max_bounces); } -ccl_device_noinline bool light_sample( - KernelGlobals *kg, float randu, float randv, float time, float3 P, int bounce, LightSample *ls) +ccl_device_noinline bool light_sample(KernelGlobals *kg, + int lamp, + float randu, + float randv, + float time, + float3 P, + int bounce, + LightSample *ls) { - /* sample index */ - int index = light_distribution_sample(kg, &randu); - - /* fetch light data */ - const ccl_global KernelLightDistribution *kdistribution = &kernel_tex_fetch(__light_distribution, - index); - int prim = kdistribution->prim; - - if (prim >= 0) { - int object = kdistribution->mesh_light.object_id; - int shader_flag = kdistribution->mesh_light.shader_flag; + if (lamp < 0) { + /* sample index */ + int index = light_distribution_sample(kg, &randu); + + /* fetch light data */ + const ccl_global KernelLightDistribution *kdistribution = &kernel_tex_fetch( + __light_distribution, index); + int prim = kdistribution->prim; + + if (prim >= 0) { + int object = kdistribution->mesh_light.object_id; + int shader_flag = kdistribution->mesh_light.shader_flag; + + triangle_light_sample(kg, prim, object, randu, randv, time, ls, P); + ls->shader |= shader_flag; + return (ls->pdf > 0.0f); + } - triangle_light_sample(kg, prim, object, randu, randv, time, ls, P); - ls->shader |= shader_flag; - return (ls->pdf > 0.0f); + lamp = -prim - 1; } - else { - int lamp = -prim - 1; - if (UNLIKELY(light_select_reached_max_bounces(kg, lamp, bounce))) { - return false; - } - - return lamp_light_sample(kg, lamp, randu, randv, P, ls); + if (UNLIKELY(light_select_reached_max_bounces(kg, lamp, bounce))) { + return false; } + + return lamp_light_sample(kg, lamp, randu, randv, P, ls); } -ccl_device int light_select_num_samples(KernelGlobals *kg, int index) +ccl_device_inline int light_select_num_samples(KernelGlobals *kg, int index) { return kernel_tex_fetch(__lights, index).samples; } |