From e29a45b396ccf507d858ec4afc301bdaf816b328 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 10 Feb 2014 21:44:49 +0100 Subject: Cycles: Separation of Indirect and Direct clamping. Indirect and Direct samples can now be clamped individually. This way we can clamp the indirect samples (fireflies), while keeping the direct highlights. Example render: http://www.pasteall.org/pic/show.php?id=66586 WARNING: This breaks backwards compatibility. If you had Clamping enabled in an old file, you must re-enable either Direct/Indirect clamping or both again. Reviewed by: brecht Differential Revision: https://developer.blender.org/D303 --- intern/cycles/kernel/kernel_accumulate.h | 67 +++++++++++++++++++------------- 1 file changed, 40 insertions(+), 27 deletions(-) (limited to 'intern/cycles/kernel/kernel_accumulate.h') diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h index 24e9d7b8858..80f3bfd33a0 100644 --- a/intern/cycles/kernel/kernel_accumulate.h +++ b/intern/cycles/kernel/kernel_accumulate.h @@ -316,15 +316,50 @@ ccl_device_inline void path_radiance_reset_indirect(PathRadiance *L) #endif } -ccl_device_inline float3 path_radiance_sum(KernelGlobals *kg, PathRadiance *L) +ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadiance *L) { #ifdef __PASSES__ if(L->use_light_pass) { path_radiance_sum_indirect(L); - float3 L_sum = L->emission - + L->direct_diffuse + L->direct_glossy + L->direct_transmission + L->direct_subsurface - + L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission + L->indirect_subsurface; + float3 L_direct = L->direct_diffuse + L->direct_glossy + L->direct_transmission + L->direct_subsurface + L->emission; + float3 L_indirect = L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission + L->indirect_subsurface; + +#ifdef __CLAMP_SAMPLE__ + float clamp_direct = kernel_data.integrator.sample_clamp_direct; + float clamp_indirect = kernel_data.integrator.sample_clamp_indirect; + + if(clamp_direct != FLT_MAX || clamp_indirect != FLT_MAX) { + float scale; + + /* Direct */ + float sum_direct = fabsf(L_direct.x) + fabsf(L_direct.y) + fabsf(L_direct.z); + if(sum_direct > clamp_direct) { + scale = clamp_direct/sum_direct; + L_direct *= scale; + + L->direct_diffuse *= scale; + L->direct_glossy *= scale; + L->direct_transmission *= scale; + L->direct_subsurface *= scale; + L->emission *= scale; + } + + /* Indirect */ + float sum_indirect = fabsf(L_indirect.x) + fabsf(L_indirect.y) + fabsf(L_indirect.z); + if(sum_indirect > clamp_indirect) { + scale = clamp_indirect/sum_indirect; + L_indirect *= scale; + + L->indirect_diffuse *= scale; + L->indirect_glossy *= scale; + L->indirect_transmission *= scale; + L->indirect_subsurface *= scale; + } + } +#endif + /* Combine */ + float3 L_sum = L_direct + L_indirect; if(!kernel_data.background.transparent) L_sum += L->background; @@ -338,7 +373,7 @@ ccl_device_inline float3 path_radiance_sum(KernelGlobals *kg, PathRadiance *L) #endif } -ccl_device_inline void path_radiance_clamp(PathRadiance *L, float3 *L_sum, float clamp) +ccl_device_inline void path_radiance_reject(PathRadiance *L, float3 *L_sum) { float sum = fabsf((*L_sum).x) + fabsf((*L_sum).y) + fabsf((*L_sum).z); @@ -360,28 +395,6 @@ ccl_device_inline void path_radiance_clamp(PathRadiance *L, float3 *L_sum, float L->emission = make_float3(0.0f, 0.0f, 0.0f); } -#endif - } - else if(sum > clamp) { - /* value to high, scale down */ - float scale = clamp/sum; - - *L_sum *= scale; - -#ifdef __PASSES__ - if(L->use_light_pass) { - L->direct_diffuse *= scale; - L->direct_glossy *= scale; - L->direct_transmission *= scale; - L->direct_subsurface *= scale; - - L->indirect_diffuse *= scale; - L->indirect_glossy *= scale; - L->indirect_transmission *= scale; - L->indirect_subsurface *= scale; - - L->emission *= scale; - } #endif } } -- cgit v1.2.3