From 37d9e65ddfe04ca8bac3c983515066b9eb78dcba Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 28 Aug 2017 13:33:37 +0200 Subject: Code cleanup: abstract shadow catcher logic more into accumulation code. --- intern/cycles/kernel/kernel_accumulate.h | 232 +++++++++++++++++++------------ 1 file changed, 142 insertions(+), 90 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 82d3c153bf5..5e604586557 100644 --- a/intern/cycles/kernel/kernel_accumulate.h +++ b/intern/cycles/kernel/kernel_accumulate.h @@ -226,9 +226,9 @@ ccl_device_inline void path_radiance_init(PathRadiance *L, int use_light_pass) L->path_total = make_float3(0.0f, 0.0f, 0.0f); L->path_total_shaded = make_float3(0.0f, 0.0f, 0.0f); L->shadow_background_color = make_float3(0.0f, 0.0f, 0.0f); - L->shadow_radiance_sum = make_float3(0.0f, 0.0f, 0.0f); L->shadow_throughput = 0.0f; L->shadow_transparency = 1.0f; + L->has_shadow_catcher = 0; #endif #ifdef __DENOISING_FEATURES__ @@ -279,13 +279,22 @@ ccl_device_inline void path_radiance_bsdf_bounce(PathRadiance *L, ccl_addr_space } } -ccl_device_inline void path_radiance_accum_emission(PathRadiance *L, float3 throughput, float3 value, int bounce) +ccl_device_inline void path_radiance_accum_emission(PathRadiance *L, + ccl_addr_space PathState *state, + float3 throughput, + float3 value) { +#ifdef __SHADOW_TRICKS__ + if(state->flag & PATH_RAY_SHADOW_CATCHER) { + return; + } +#endif + #ifdef __PASSES__ if(L->use_light_pass) { - if(bounce == 0) + if(state->bounce == 0) L->emission += throughput*value; - else if(bounce == 1) + else if(state->bounce == 1) L->direct_emission += throughput*value; else L->indirect += throughput*value; @@ -304,6 +313,18 @@ ccl_device_inline void path_radiance_accum_ao(PathRadiance *L, float3 bsdf, float3 ao) { +#ifdef __SHADOW_TRICKS__ + if(state->flag & PATH_RAY_STORE_SHADOW_INFO) { + float3 light = throughput * bsdf; + L->path_total += light; + L->path_total_shaded += ao * light; + + if(state->flag & PATH_RAY_SHADOW_CATCHER) { + return; + } + } +#endif + #ifdef __PASSES__ if(L->use_light_pass) { if(state->bounce == 0) { @@ -321,14 +342,6 @@ ccl_device_inline void path_radiance_accum_ao(PathRadiance *L, { L->emission += throughput*bsdf*ao; } - -#ifdef __SHADOW_TRICKS__ - if(state->flag & PATH_RAY_STORE_SHADOW_INFO) { - float3 light = throughput * bsdf; - L->path_total += light; - L->path_total_shaded += ao * light; - } -#endif } ccl_device_inline void path_radiance_accum_total_ao( @@ -357,6 +370,18 @@ ccl_device_inline void path_radiance_accum_light(PathRadiance *L, float shadow_fac, bool is_lamp) { +#ifdef __SHADOW_TRICKS__ + if(state->flag & PATH_RAY_STORE_SHADOW_INFO) { + float3 light = throughput * bsdf_eval->sum_no_mis; + L->path_total += light; + L->path_total_shaded += shadow * light; + + if(state->flag & PATH_RAY_SHADOW_CATCHER) { + return; + } + } +#endif + #ifdef __PASSES__ if(L->use_light_pass) { if(state->bounce == 0) { @@ -383,14 +408,6 @@ ccl_device_inline void path_radiance_accum_light(PathRadiance *L, { L->emission += throughput*bsdf_eval->diffuse*shadow; } - -#ifdef __SHADOW_TRICKS__ - if(state->flag & PATH_RAY_STORE_SHADOW_INFO) { - float3 light = throughput * bsdf_eval->sum_no_mis; - L->path_total += light; - L->path_total_shaded += shadow * light; - } -#endif } ccl_device_inline void path_radiance_accum_total_light( @@ -417,6 +434,18 @@ ccl_device_inline void path_radiance_accum_background( float3 throughput, float3 value) { + +#ifdef __SHADOW_TRICKS__ + if(state->flag & PATH_RAY_STORE_SHADOW_INFO) { + L->path_total += throughput * value; + L->path_total_shaded += throughput * value * L->shadow_transparency; + + if(state->flag & PATH_RAY_SHADOW_CATCHER) { + return; + } + } +#endif + #ifdef __PASSES__ if(L->use_light_pass) { if(state->bounce == 0) @@ -432,18 +461,31 @@ ccl_device_inline void path_radiance_accum_background( L->emission += throughput*value; } -#ifdef __SHADOW_TRICKS__ - if(state->flag & PATH_RAY_STORE_SHADOW_INFO) { - L->path_total += throughput * value; - L->path_total_shaded += throughput * value * L->shadow_transparency; - } -#endif - #ifdef __DENOISING_FEATURES__ L->denoising_albedo += state->denoising_feature_weight * value; #endif /* __DENOISING_FEATURES__ */ } +ccl_device_inline void path_radiance_accum_transparent( + PathRadiance *L, + ccl_addr_space PathState *state, + float3 throughput) +{ + L->transparent += average(throughput); +} + +#ifdef __SHADOW_TRICKS__ +ccl_device_inline void path_radiance_accum_shadowcatcher( + PathRadiance *L, + float3 throughput, + float3 background) +{ + L->shadow_throughput += average(throughput); + L->shadow_background_color += throughput * background; + L->has_shadow_catcher = 1; +} +#endif + ccl_device_inline void path_radiance_sum_indirect(PathRadiance *L) { #ifdef __PASSES__ @@ -501,7 +543,36 @@ ccl_device_inline void path_radiance_copy_indirect(PathRadiance *L, #endif } -ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadiance *L) +#ifdef __SHADOW_TRICKS__ +ccl_device_inline void path_radiance_sum_shadowcatcher(KernelGlobals *kg, + PathRadiance *L, + float3 *L_sum, + float *alpha) +{ + /* Calculate current shadow of the path. */ + float path_total = average(L->path_total); + float shadow; + + if(path_total == 0.0f) { + shadow = L->shadow_transparency; + } + else { + float path_total_shaded = average(L->path_total_shaded); + shadow = path_total_shaded / path_total; + } + + /* Calculate final light sum and transparency for shadow catcher object. */ + if(kernel_data.background.transparent) { + *alpha -= L->shadow_throughput * shadow; + } + else { + L->shadow_background_color *= shadow; + *L_sum += L->shadow_background_color; + } +} +#endif + +ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadiance *L, float *alpha) { float3 L_sum; /* Light Passes are used */ @@ -578,8 +649,6 @@ ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadi L_sum = L_direct + L_indirect; } #endif - - return L_sum; } /* No Light Passes */ @@ -587,14 +656,24 @@ ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadi #endif { L_sum = L->emission; + + /* Reject invalid value */ + float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z); + if(!isfinite_safe(sum)) { + kernel_assert(!"Non-finite final sum in path_radiance_clamp_and_sum!"); + L_sum = make_float3(0.0f, 0.0f, 0.0f); + } } - /* Reject invalid value */ - float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z); - if(!isfinite_safe(sum)) { - kernel_assert(!"Non-finite final sum in path_radiance_clamp_and_sum!"); - L_sum = make_float3(0.0f, 0.0f, 0.0f); + /* Compute alpha. */ + *alpha = 1.0f - L->transparent; + + /* Add shadow catcher contributions. */ +#ifdef __SHADOW_TRICKS__ + if(L->has_shadow_catcher) { + path_radiance_sum_shadowcatcher(kg, L, &L_sum, alpha); } +#endif /* __SHADOW_TRICKS__ */ return L_sum; } @@ -627,14 +706,18 @@ ccl_device_inline void path_radiance_split_denoising(KernelGlobals *kg, PathRadi *clean = make_float3(0.0f, 0.0f, 0.0f); #endif +#ifdef __SHADOW_TRICKS__ + if(L->has_shadow_catcher) { + *noisy += L->shadow_background_color; + } +#endif + *noisy = ensure_finite3(*noisy); *clean = ensure_finite3(*clean); } -ccl_device_inline void path_radiance_accum_sample(PathRadiance *L, PathRadiance *L_sample, int num_samples) +ccl_device_inline void path_radiance_accum_sample(PathRadiance *L, PathRadiance *L_sample) { - float fac = 1.0f/num_samples; - #ifdef __SPLIT_KERNEL__ # define safe_float3_add(f, v) \ do { \ @@ -643,66 +726,35 @@ ccl_device_inline void path_radiance_accum_sample(PathRadiance *L, PathRadiance atomic_add_and_fetch_float(p+1, (v).y); \ atomic_add_and_fetch_float(p+2, (v).z); \ } while(0) +# define safe_float_add(f, v) \ + atomic_add_and_fetch_float(&(f), (v)) #else # define safe_float3_add(f, v) (f) += (v) +# define safe_float_add(f, v) (f) += (v) #endif /* __SPLIT_KERNEL__ */ #ifdef __PASSES__ - safe_float3_add(L->direct_diffuse, L_sample->direct_diffuse*fac); - safe_float3_add(L->direct_glossy, L_sample->direct_glossy*fac); - safe_float3_add(L->direct_transmission, L_sample->direct_transmission*fac); - safe_float3_add(L->direct_subsurface, L_sample->direct_subsurface*fac); - safe_float3_add(L->direct_scatter, L_sample->direct_scatter*fac); - - safe_float3_add(L->indirect_diffuse, L_sample->indirect_diffuse*fac); - safe_float3_add(L->indirect_glossy, L_sample->indirect_glossy*fac); - safe_float3_add(L->indirect_transmission, L_sample->indirect_transmission*fac); - safe_float3_add(L->indirect_subsurface, L_sample->indirect_subsurface*fac); - safe_float3_add(L->indirect_scatter, L_sample->indirect_scatter*fac); - - safe_float3_add(L->background, L_sample->background*fac); - safe_float3_add(L->ao, L_sample->ao*fac); - safe_float3_add(L->shadow, L_sample->shadow*fac); -# ifdef __SPLIT_KERNEL__ - atomic_add_and_fetch_float(&L->mist, L_sample->mist*fac); -# else - L->mist += L_sample->mist*fac; -# endif /* __SPLIT_KERNEL__ */ + safe_float3_add(L->direct_diffuse, L_sample->direct_diffuse); + safe_float3_add(L->direct_glossy, L_sample->direct_glossy); + safe_float3_add(L->direct_transmission, L_sample->direct_transmission); + safe_float3_add(L->direct_subsurface, L_sample->direct_subsurface); + safe_float3_add(L->direct_scatter, L_sample->direct_scatter); + + safe_float3_add(L->indirect_diffuse, L_sample->indirect_diffuse); + safe_float3_add(L->indirect_glossy, L_sample->indirect_glossy); + safe_float3_add(L->indirect_transmission, L_sample->indirect_transmission); + safe_float3_add(L->indirect_subsurface, L_sample->indirect_subsurface); + safe_float3_add(L->indirect_scatter, L_sample->indirect_scatter); + + safe_float3_add(L->background, L_sample->background); + safe_float3_add(L->ao, L_sample->ao); + safe_float3_add(L->shadow, L_sample->shadow); + safe_float_add(L->mist, L_sample->mist); #endif /* __PASSES__ */ - safe_float3_add(L->emission, L_sample->emission*fac); + safe_float3_add(L->emission, L_sample->emission); +#undef safe_float_add #undef safe_float3_add } -#ifdef __SHADOW_TRICKS__ -/* Calculate current shadow of the path. */ -ccl_device_inline float path_radiance_sum_shadow(const PathRadiance *L) -{ - float path_total = average(L->path_total); - float path_total_shaded = average(L->path_total_shaded); - if(path_total != 0.0f) { - return path_total_shaded / path_total; - } - return L->shadow_transparency; -} - -/* Calculate final light sum and transparency for shadow catcher object. */ -ccl_device_inline float3 path_radiance_sum_shadowcatcher(KernelGlobals *kg, - const PathRadiance *L, - float* alpha) -{ - const float shadow = path_radiance_sum_shadow(L); - float3 L_sum; - if(kernel_data.background.transparent) { - *alpha = 1.0f - L->shadow_throughput * shadow; - L_sum = L->shadow_radiance_sum; - } - else { - L_sum = L->shadow_background_color * L->shadow_throughput * shadow + - L->shadow_radiance_sum; - } - return L_sum; -} -#endif - CCL_NAMESPACE_END -- cgit v1.2.3