From 0967b39be1cf9644454e1d4e9c6d0250d9a36e85 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 15 Jan 2013 19:17:51 +0000 Subject: [PATCH] Fix #33838: light render passes for non-progressive integrator were not correct. --- intern/cycles/kernel/kernel_accumulate.h | 55 +++++++++++++++++------- intern/cycles/kernel/kernel_path.h | 5 +++ intern/cycles/kernel/kernel_types.h | 4 ++ 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h index d99beb8905a..23bd29840ec 100644 --- a/intern/cycles/kernel/kernel_accumulate.h +++ b/intern/cycles/kernel/kernel_accumulate.h @@ -133,6 +133,10 @@ __device_inline void path_radiance_init(PathRadiance *L, int use_light_pass) L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f); L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f); + L->path_diffuse = make_float3(0.0f, 0.0f, 0.0f); + L->path_glossy = make_float3(0.0f, 0.0f, 0.0f); + L->path_transmission = make_float3(0.0f, 0.0f, 0.0f); + L->emission = make_float3(0.0f, 0.0f, 0.0f); L->background = make_float3(0.0f, 0.0f, 0.0f); L->ao = make_float3(0.0f, 0.0f, 0.0f); @@ -156,11 +160,11 @@ __device_inline void path_radiance_bsdf_bounce(PathRadiance *L, float3 *throughp /* first on directly visible surface */ float3 value = *throughput*inverse_pdf; - L->indirect_diffuse = bsdf_eval->diffuse*value; - L->indirect_glossy = bsdf_eval->glossy*value; - L->indirect_transmission = bsdf_eval->transmission*value; + L->path_diffuse = bsdf_eval->diffuse*value; + L->path_glossy = bsdf_eval->glossy*value; + L->path_transmission = bsdf_eval->transmission*value; - *throughput = L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission; + *throughput = L->path_diffuse + L->path_glossy + L->path_transmission; L->direct_throughput = *throughput; } @@ -266,22 +270,41 @@ __device_inline void path_radiance_accum_background(PathRadiance *L, float3 thro #endif } +__device_inline void path_radiance_sum_indirect(PathRadiance *L) +{ + /* this division is a bit ugly, but means we only have to keep track of + * only a single throughput further along the path, here we recover just + * the indirect parth that is not influenced by any particular BSDF type */ + if(L->use_light_pass) { + L->direct_emission = safe_divide_color(L->direct_emission, L->direct_throughput); + L->direct_diffuse += L->path_diffuse*L->direct_emission; + L->direct_glossy += L->path_glossy*L->direct_emission; + L->direct_transmission += L->path_transmission*L->direct_emission; + + L->indirect = safe_divide_color(L->indirect, L->direct_throughput); + L->indirect_diffuse += L->path_diffuse*L->indirect; + L->indirect_glossy += L->path_glossy*L->indirect; + L->indirect_transmission += L->path_transmission*L->indirect; + } +} + +__device_inline void path_radiance_reset_indirect(PathRadiance *L) +{ + if(L->use_light_pass) { + L->path_diffuse = make_float3(0.0f, 0.0f, 0.0f); + L->path_glossy = make_float3(0.0f, 0.0f, 0.0f); + L->path_transmission = make_float3(0.0f, 0.0f, 0.0f); + + L->direct_emission = make_float3(0.0f, 0.0f, 0.0f); + L->indirect = make_float3(0.0f, 0.0f, 0.0f); + } +} + __device_inline float3 path_radiance_sum(KernelGlobals *kg, PathRadiance *L) { #ifdef __PASSES__ if(L->use_light_pass) { - /* this division is a bit ugly, but means we only have to keep track of - * only a single throughput further along the path, here we recover just - * the indirect parth that is not influenced by any particular BSDF type */ - L->direct_emission = safe_divide_color(L->direct_emission, L->direct_throughput); - L->direct_diffuse += L->indirect_diffuse*L->direct_emission; - L->direct_glossy += L->indirect_glossy*L->direct_emission; - L->direct_transmission += L->indirect_transmission*L->direct_emission; - - L->indirect = safe_divide_color(L->indirect, L->direct_throughput); - L->indirect_diffuse *= L->indirect; - L->indirect_glossy *= L->indirect; - L->indirect_transmission *= L->indirect; + path_radiance_sum_indirect(L); float3 L_sum = L->emission + L->direct_diffuse + L->direct_glossy + L->direct_transmission diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 532c32896d9..1a5df66e6c2 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -949,6 +949,11 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam kernel_path_indirect(kg, rng, sample*num_samples + j, bsdf_ray, buffer, tp*num_samples_inv, num_samples, min_ray_pdf, bsdf_pdf, ps, rng_offset+PRNG_BOUNCE_NUM, &L); + + /* for render passes, sum and reset indirect light pass variables + * for the next samples */ + path_radiance_sum_indirect(&L); + path_radiance_reset_indirect(&L); } } diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 149a4470515..83c157b1f36 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -255,6 +255,10 @@ typedef struct PathRadiance { float3 indirect_glossy; float3 indirect_transmission; + float3 path_diffuse; + float3 path_glossy; + float3 path_transmission; + float4 shadow; } PathRadiance;