Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Werner <swerner@smithmicro.com>2015-11-20 19:44:19 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2015-11-26 12:59:58 +0300
commitc8a041f4895bbffc3efbede9c6003961cd59efaa (patch)
tree781f78f32e8570abe8ded334228e54fc372b8faf /intern/cycles/kernel/kernel_shader.h
parent35cf545e3a9018650f7b529aececb88072974083 (diff)
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.
Diffstat (limited to 'intern/cycles/kernel/kernel_shader.h')
-rw-r--r--intern/cycles/kernel/kernel_shader.h46
1 files changed, 43 insertions, 3 deletions
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 6b560f5fdb2..25e5822a21b 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,