[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