[Bf-blender-cvs] [1f432d2] soc-2014-cycles: Cycles: Optimization for Heterogeneous Volume Shadows.

Thomas Dinges noreply at git.blender.org
Wed Jul 30 20:03:42 CEST 2014


Commit: 1f432d2b06c426cb4c0e6adb54b37ab8a298c149
Author: Thomas Dinges
Date:   Wed Jul 30 19:59:15 2014 +0200
Branches: soc-2014-cycles
https://developer.blender.org/rB1f432d2b06c426cb4c0e6adb54b37ab8a298c149

Cycles: Optimization for Heterogeneous Volume Shadows.

* Don't compute expf() for every step, instead sum the intermediate values and calculate it every N (8 for now) steps.

This helps a few percent (~5% on a cube with wave texture) in my tests here.

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

M	intern/cycles/kernel/kernel_volume.h

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

diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index cc4b2e3..2f61eb7 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -176,6 +176,9 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg, PathState
 	/* compute extinction at the start */
 	float t = 0.0f;
 
+	float3 sum = make_float3(0.0f, 0.0f, 0.0f);
+	bool tp_calculated = false;
+
 	for(int i = 0; i < max_steps; i++) {
 		/* advance to new position */
 		float new_t = min(ray->t, (i+1) * step);
@@ -190,20 +193,30 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg, PathState
 
 		/* compute attenuation over segment */
 		if(volume_shader_extinction_sample(kg, sd, state, new_P, &sigma_t)) {
-			/* todo: we could avoid computing expf() for each step by summing,
-			 * because exp(a)*exp(b) = exp(a+b), but we still want a quick
-			 * tp_eps check too */
-			tp *= volume_color_transmittance(sigma_t, new_t - t);
-
-			/* stop if nearly all light blocked */
-			if(tp.x < tp_eps && tp.y < tp_eps && tp.z < tp_eps)
-				break;
+			/* Compute expf() only for every Nth step, to save some calculations
+			 * because exp(a)*exp(b) = exp(a+b), also do a quick tp_eps check then. */
+
+			sum += (-sigma_t * (new_t - t));
+			if((i % 8) == 0) { /* ToDo: Other interval? */
+				tp_calculated = true;
+				tp = *throughput * make_float3(expf(sum.x), expf(sum.y), expf(sum.z));
+
+				/* stop if nearly all light blocked */
+				if(tp.x < tp_eps && tp.y < tp_eps && tp.z < tp_eps)
+					break;
+			}
+			else
+				tp_calculated = false;
 		}
 
 		/* stop if at the end of the volume */
 		t = new_t;
-		if(t == ray->t)
+		if(t == ray->t) {
+			if(!tp_calculated)
+				/* Update throughput in case we have't done it above */
+				tp = *throughput * make_float3(expf(sum.x), expf(sum.y), expf(sum.z));
 			break;
+		}
 	}
 
 	*throughput = tp;




More information about the Bf-blender-cvs mailing list