[Bf-blender-cvs] [c8a041f] master: Fix T46760: Branched Path Tracing converges to different result than plain Path Tracing

Stefan Werner noreply at git.blender.org
Thu Nov 26 12:14:05 CET 2015


Commit: c8a041f4895bbffc3efbede9c6003961cd59efaa
Author: Stefan Werner
Date:   Fri Nov 20 17:44:19 2015 +0100
Branches: master
https://developer.blender.org/rBc8a041f4895bbffc3efbede9c6003961cd59efaa

Fix T46760: Branched Path Tracing converges to different result than plain Path Tracing

Multiple importance sampling for branched path tracing light samples needs to be
calculated separately per BSDF, not with Veach's one sample model.

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

M	intern/cycles/kernel/kernel_emission.h
M	intern/cycles/kernel/kernel_shader.h

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

diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index de9e8d7..3863cf2 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -99,23 +99,23 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd,
 		return false;
 
 	/* evaluate BSDF at shading point */
-	float bsdf_pdf;
 
 #ifdef __VOLUME__
 	if(ccl_fetch(sd, prim) != PRIM_NONE)
-		shader_bsdf_eval(kg, sd, ls->D, eval, &bsdf_pdf);
-	else
+		shader_bsdf_eval(kg, sd, ls->D, eval, ls->pdf, ls->shader & SHADER_USE_MIS);
+	else {
+		float bsdf_pdf;
 		shader_volume_phase_eval(kg, sd, ls->D, eval, &bsdf_pdf);
+		if(ls->shader & SHADER_USE_MIS) {
+			/* Multiple importance sampling. */
+			float mis_weight = power_heuristic(ls->pdf, bsdf_pdf);
+			light_eval *= mis_weight;
+		}
+	}
 #else
-	shader_bsdf_eval(kg, sd, ls->D, eval, &bsdf_pdf);
+	shader_bsdf_eval(kg, sd, ls->D, eval, ls->pdf, ls->shader & SHADER_USE_MIS);
 #endif
 
-	if(ls->shader & SHADER_USE_MIS) {
-		/* multiple importance sampling */
-		float mis_weight = power_heuristic(ls->pdf, bsdf_pdf);
-		light_eval *= mis_weight;
-	}
-	
 	bsdf_eval_mul(eval, light_eval/ls->pdf);
 
 #ifdef __PASSES__
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 6b560f5..25e5822 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -516,12 +516,52 @@ ccl_device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg, const ShaderDa
 	*pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f;
 }
 
-ccl_device void shader_bsdf_eval(KernelGlobals *kg, ShaderData *sd,
-	const float3 omega_in, BsdfEval *eval, float *pdf)
+#ifdef __BRANCHED_PATH__
+ccl_device_inline void _shader_bsdf_multi_eval_branched(KernelGlobals *kg,
+                                                        const ShaderData *sd,
+                                                        const float3 omega_in,
+                                                        BsdfEval *result_eval,
+                                                        float light_pdf,
+                                                        bool use_mis)
+{
+	for(int i = 0; i < ccl_fetch(sd, num_closure); i++) {
+		const ShaderClosure *sc = ccl_fetch_array(sd, closure, i);
+		if(CLOSURE_IS_BSDF(sc->type)) {
+			float bsdf_pdf = 0.0f;
+			float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
+			if(bsdf_pdf != 0.0f) {
+				float mis_weight = use_mis? power_heuristic(light_pdf, bsdf_pdf): 1.0f;
+				bsdf_eval_accum(result_eval,
+				                sc->type,
+				                eval * sc->weight * mis_weight);
+			}
+		}
+	}
+}
+#endif
+
+ccl_device void shader_bsdf_eval(KernelGlobals *kg,
+                                 ShaderData *sd,
+                                 const float3 omega_in,
+                                 BsdfEval *eval,
+                                 float light_pdf,
+                                 bool use_mis)
 {
 	bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
 
-	_shader_bsdf_multi_eval(kg, sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
+#ifdef __BRANCHED_PATH__
+	if(kernel_data.integrator.branched)
+		_shader_bsdf_multi_eval_branched(kg, sd, omega_in, eval, light_pdf, use_mis);
+	else
+#endif
+	{
+		float pdf;
+		_shader_bsdf_multi_eval(kg, sd, omega_in, &pdf, -1, eval, 0.0f, 0.0f);
+		if(use_mis) {
+			float weight = power_heuristic(light_pdf, pdf);
+			bsdf_eval_mul(eval, make_float3(weight, weight, weight));
+		}
+	}
 }
 
 ccl_device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,




More information about the Bf-blender-cvs mailing list