From 71195b247e34432196242b764301043cbef3a162 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 28 Sep 2012 13:41:34 +0000 Subject: [PATCH] Fix #32072: cycles shadow pass gave different results with/without emitting materials present, even though it's only taking lamp shadows into account. --- intern/cycles/kernel/kernel_passes.h | 14 ++++++++++++-- intern/cycles/render/buffers.cpp | 13 ++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h index f3ddda4a392..42733d691e0 100644 --- a/intern/cycles/kernel/kernel_passes.h +++ b/intern/cycles/kernel/kernel_passes.h @@ -125,8 +125,18 @@ __device_inline void kernel_write_light_passes(KernelGlobals *kg, __global float kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_color, sample, L->color_glossy); if(flag & PASS_TRANSMISSION_COLOR) kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_color, sample, L->color_transmission); - if(flag & PASS_SHADOW) - kernel_write_pass_float4(buffer + kernel_data.film.pass_shadow, sample, L->shadow); + if(flag & PASS_SHADOW) { + float4 shadow = L->shadow; + + /* bit of an ugly hack to compensate for emitting triangles influencing + * amount of samples we get for this pass */ + if(kernel_data.integrator.progressive && kernel_data.integrator.pdf_triangles != 0.0f) + shadow.w = 0.5f; + else + shadow.w = 1.0f; + + kernel_write_pass_float4(buffer + kernel_data.film.pass_shadow, sample, shadow); + } #endif } diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp index 51568f65323..6f8740b8a51 100644 --- a/intern/cycles/render/buffers.cpp +++ b/intern/cycles/render/buffers.cpp @@ -196,7 +196,18 @@ bool RenderBuffers::get_pass_rect(PassType type, float exposure, int sample, int else if(components == 3) { assert(pass.components == 4); - if(pass.divide_type != PASS_NONE) { + /* RGBA */ + if(type == PASS_SHADOW) { + for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) { + float4 f = make_float4(in[0], in[1], in[2], in[3]); + float invw = (f.w > 0.0f)? 1.0f/f.w: 1.0f; + + pixels[0] = f.x*invw; + pixels[1] = f.y*invw; + pixels[2] = f.z*invw; + } + } + else if(pass.divide_type != PASS_NONE) { /* RGB lighting passes that need to divide out color */ pass_offset = 0; foreach(Pass& color_pass, params.passes) {