[Bf-blender-cvs] [9e61dcc] master: Fix T40408: world MIS + equiangular sampling giving unnecessary noise.

Brecht Van Lommel noreply at git.blender.org
Thu May 29 14:54:41 CEST 2014


Commit: 9e61dcc6b89f21420bf64c25741c3a259c4158ba
Author: Brecht Van Lommel
Date:   Thu May 29 13:20:42 2014 +0200
https://developer.blender.org/rB9e61dcc6b89f21420bf64c25741c3a259c4158ba

Fix T40408: world MIS + equiangular sampling giving unnecessary noise.

It's actually not possible to do equiangular sampling for distant lights, now
it reverts to distance sampling in this case.

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

M	intern/cycles/kernel/kernel_volume.h

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

diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index faaa68e..75c8194 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -226,7 +226,7 @@ ccl_device float kernel_volume_equiangular_pdf(Ray *ray, float3 light_P, float s
 	return pdf;
 }
 
-ccl_device bool kernel_volume_equiangular_light_position(KernelGlobals *kg, PathState *state, Ray *ray, RNG *rng, float3 *light_P)
+ccl_device bool kernel_volume_equiangular_light_position(KernelGlobals *kg, PathState *state, Ray *ray, RNG *rng, float3 *light_P, bool *distant)
 {
 	/* light RNGs */
 	float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT);
@@ -240,17 +240,9 @@ ccl_device bool kernel_volume_equiangular_light_position(KernelGlobals *kg, Path
 		return false;
 	
 	*light_P = ls.P;
-	return true;
-}
-
-ccl_device float kernel_volume_decoupled_equiangular_pdf(KernelGlobals *kg, PathState *state, Ray *ray, RNG *rng, float sample_t)
-{
-	float3 light_P;
+	*distant = ls.t == FLT_MAX;
 
-	if(!kernel_volume_equiangular_light_position(kg, state, ray, rng, &light_P))
-		return 0.0f;
-
-	return kernel_volume_equiangular_pdf(ray, light_P, sample_t);
+	return true;
 }
 
 /* Distance sampling */
@@ -357,12 +349,20 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(KernelGloba
 				/* equiangular sampling */
 				float3 light_P;
 				float equi_pdf;
-				if(!kernel_volume_equiangular_light_position(kg, state, ray, rng, &light_P))
+				bool light_distant;
+
+				if(!kernel_volume_equiangular_light_position(kg, state, ray, rng, &light_P, &light_distant))
 					return VOLUME_PATH_MISSED;
 
-				sample_t = kernel_volume_equiangular_sample(ray, light_P, xi, &equi_pdf);
-				transmittance = volume_color_transmittance(sigma_t, sample_t);
-				pdf = make_float3(equi_pdf, equi_pdf, equi_pdf);
+				if(light_distant) {
+					/* distant light, revert to distance sampling because position is infinitely far away */
+					sample_t = kernel_volume_distance_sample(ray->t, sigma_t, channel, xi, &transmittance, &pdf);
+				}
+				else {
+					sample_t = kernel_volume_equiangular_sample(ray, light_P, xi, &equi_pdf);
+					transmittance = volume_color_transmittance(sigma_t, sample_t);
+					pdf = make_float3(equi_pdf, equi_pdf, equi_pdf);
+				}
 			}
 
 			/* modifiy pdf for hit/miss decision */
@@ -720,8 +720,23 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter(
 	float3 transmittance;
 	float pdf, sample_t;
 
+	/* pick position on light for equiangular */
+	bool equiangular = (kernel_data.integrator.volume_homogeneous_sampling != 0 && kernel_data.integrator.num_all_lights);
+	float3 light_P;
+
+	if(equiangular) {
+		bool light_distant;
+
+		if(!kernel_volume_equiangular_light_position(kg, state, ray, rng, &light_P, &light_distant))
+			return VOLUME_PATH_MISSED;
+
+		/* distant light, revert to distance sampling because position is infinitely far away */
+		if(light_distant)
+			equiangular = false;
+	}
+
 	/* distance sampling */
-	if(kernel_data.integrator.volume_homogeneous_sampling == 0 || !kernel_data.integrator.num_all_lights) { 
+	if(!equiangular) {
 		/* find step in cdf */
 		step = segment->steps;
 
@@ -762,11 +777,6 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter(
 	}
 	/* equi-angular sampling */
 	else {
-		/* pick position on light */
-		float3 light_P;
-		if(!kernel_volume_equiangular_light_position(kg, state, ray, rng, &light_P))
-			return VOLUME_PATH_MISSED;
-
 		/* sample distance */
 		sample_t = kernel_volume_equiangular_sample(ray, light_P, xi, &pdf);




More information about the Bf-blender-cvs mailing list