[Bf-blender-cvs] [9406c19] soc-2014-cycles: Cycles: Avoid redundant calculations for Lamps when using Decoupled Ray Marching.
Thomas Dinges
noreply at git.blender.org
Tue Jul 29 01:33:00 CEST 2014
Commit: 9406c19895361b324da45eb402e114ea0b55acf6
Author: Thomas Dinges
Date: Tue Jul 29 01:19:07 2014 +0200
Branches: soc-2014-cycles
https://developer.blender.org/rB9406c19895361b324da45eb402e114ea0b55acf6
Cycles: Avoid redundant calculations for Lamps when using Decoupled Ray Marching.
* Split light_sample functions, so we can only recalculate the parts, that actually change due to the new position.
Gives a few percent speedup, especially in scenes with Branched Path, and Sample All Lights.
===================================================================
M intern/cycles/kernel/kernel_light.h
M intern/cycles/kernel/kernel_path_volume.h
===================================================================
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index cd4cf2e..37230d4 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -208,6 +208,48 @@ ccl_device float lamp_light_pdf(KernelGlobals *kg, const float3 Ng, const float3
return t*t/cos_pi;
}
+ccl_device void lamp_light_sample_new_position(KernelGlobals *kg, int lamp,
+ float randu, float randv, float3 P, LightSample *ls)
+{
+ if(ls->type == LIGHT_POINT || ls->type == LIGHT_SPOT) {
+ float4 data0 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 0);
+ float4 data1 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 1);
+
+ ls->P = make_float3(data0.y, data0.z, data0.w);
+
+ float radius = data1.y;
+
+ if(radius > 0.0f)
+ /* sphere light */
+ ls->P += sphere_light_sample(P, ls->P, radius, randu, randv);
+
+ ls->D = normalize_len(ls->P - P, &ls->t);
+ ls->Ng = -ls->D;
+
+ float invarea = data1.z;
+ ls->pdf = invarea;
+
+ if(ls->type == LIGHT_SPOT) {
+ /* spot light attenuation */
+ float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
+ ls->eval_fac = (0.25f*M_1_PI_F)*invarea*kernel_data.integrator.inv_pdf_lights;
+ ls->eval_fac *= spot_light_attenuation(data1, data2, ls);
+ }
+ }
+ else if(ls->type == LIGHT_AREA) {
+ float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
+ ls->pdf = data2.x;
+
+ ls->D = normalize_len(ls->P - P, &ls->t);
+ }
+ else {
+ /* Distant Lights */
+ return;
+ }
+
+ ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
+}
+
ccl_device void lamp_light_sample(KernelGlobals *kg, int lamp,
float randu, float randv, float3 P, LightSample *ls)
{
@@ -512,6 +554,27 @@ ccl_device int light_distribution_sample(KernelGlobals *kg, float randt)
return clamp(first-1, 0, kernel_data.integrator.num_distribution-1);
}
+/* ToDo: Better function name */
+ccl_device void light_sample_new_position(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, LightSample *ls)
+{
+ /* sample index */
+ int index = light_distribution_sample(kg, randt);
+
+ /* fetch light data */
+ float4 l = kernel_tex_fetch(__light_distribution, index);
+ int prim = __float_as_int(l.y);
+
+ if(prim >= 0) {
+ /* compute incoming direction, distance and pdf */
+ ls->D = normalize_len(ls->P - P, &ls->t);
+ ls->pdf = triangle_light_pdf(kg, ls->Ng, -ls->D, ls->t);
+ }
+ else {
+ int lamp = -prim-1;
+ lamp_light_sample_new_position(kg, lamp, randu, randv, P, ls);
+ }
+}
+
/* Generic Light */
ccl_device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, LightSample *ls)
diff --git a/intern/cycles/kernel/kernel_path_volume.h b/intern/cycles/kernel/kernel_path_volume.h
index f712199..32980ad 100644
--- a/intern/cycles/kernel/kernel_path_volume.h
+++ b/intern/cycles/kernel/kernel_path_volume.h
@@ -149,8 +149,7 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
if(result != VOLUME_PATH_SCATTERED)
continue;
- /* todo: split up light_sample so we don't have to call it again with new position */
- lamp_light_sample(kg, i, light_u, light_v, sd->P, &ls);
+ lamp_light_sample_new_position(kg, i, light_u, light_v, sd->P, &ls);
}
if(ls.pdf == 0.0f)
@@ -202,8 +201,7 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
if(result != VOLUME_PATH_SCATTERED)
continue;
- /* 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_new_position(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
}
if(ls.pdf == 0.0f)
@@ -243,8 +241,7 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
if(result != VOLUME_PATH_SCATTERED)
return;
- /* 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_new_position(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
}
if(ls.pdf == 0.0f)
More information about the Bf-blender-cvs
mailing list