diff options
-rw-r--r-- | intern/cycles/kernel/kernel_emission.h | 20 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_shader.h | 46 |
2 files changed, 53 insertions, 13 deletions
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index de9e8d77ec8..3863cf221c5 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 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, |