From d8066fb0f145395594d0a952a4c0f70206dc0214 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Sun, 5 Nov 2017 21:43:23 +0100 Subject: [PATCH] Cycles: Refactor closure roughness detection to fix a potential bug with Denoising of specular shaders --- intern/cycles/kernel/closure/bsdf.h | 34 +++++++++++++--------------- intern/cycles/kernel/kernel_passes.h | 2 +- intern/cycles/kernel/svm/svm_types.h | 9 +++++--- intern/cycles/util/util_math.h | 5 ++++ 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index 0a3f9ff23fe..e4573024e85 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -36,6 +36,22 @@ CCL_NAMESPACE_BEGIN +/* Returns the square of the roughness of the closure if it has roughness, + * 0 for singular closures and 1 otherwise. */ +ccl_device_inline float bsdf_get_roughness_sqr(const ShaderClosure *sc) +{ + if(CLOSURE_IS_BSDF_SINGULAR(sc->type)) { + return 0.0f; + } + + if(CLOSURE_IS_BSDF_MICROFACET(sc->type)) { + MicrofacetBsdf *bsdf = (MicrofacetBsdf*) sc; + return bsdf->alpha_x*bsdf->alpha_y; + } + + return 1.0f; +} + ccl_device_forceinline int bsdf_sample(KernelGlobals *kg, ShaderData *sd, const ShaderClosure *sc, @@ -438,23 +454,5 @@ ccl_device bool bsdf_merge(ShaderClosure *a, ShaderClosure *b) #endif } -/* Classifies a closure as diffuse-like or specular-like. - * This is needed for the denoising feature pass generation, - * which are written on the first bounce where more than 25% - * of the sampling weight belongs to diffuse-line closures. */ -ccl_device_inline bool bsdf_is_specular_like(ShaderClosure *sc) -{ - if(CLOSURE_IS_BSDF_TRANSPARENT(sc->type)) { - return true; - } - - if(CLOSURE_IS_BSDF_MICROFACET(sc->type)) { - MicrofacetBsdf *bsdf = (MicrofacetBsdf*) sc; - return (bsdf->alpha_x*bsdf->alpha_y <= 0.075f*0.075f); - } - - return false; -} - CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h index b31356905f2..6bed73ad459 100644 --- a/intern/cycles/kernel/kernel_passes.h +++ b/intern/cycles/kernel/kernel_passes.h @@ -140,7 +140,7 @@ ccl_device_inline void kernel_update_denoising_features(KernelGlobals *kg, /* All closures contribute to the normal feature, but only diffuse-like ones to the albedo. */ normal += sc->N * sc->sample_weight; sum_weight += sc->sample_weight; - if(!bsdf_is_specular_like(sc)) { + if(bsdf_get_roughness_sqr(sc) > sqr(0.075f)) { albedo += sc->weight; sum_nonspecular_weight += sc->sample_weight; } diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index f08ec76c055..c7fe7948422 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -465,13 +465,16 @@ typedef enum ClosureType { #define CLOSURE_IS_BSDF_GLOSSY(type) (type >= CLOSURE_BSDF_REFLECTION_ID && type <= CLOSURE_BSDF_HAIR_REFLECTION_ID) #define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSLUCENT_ID && type <= CLOSURE_BSDF_HAIR_TRANSMISSION_ID) #define CLOSURE_IS_BSDF_BSSRDF(type) (type == CLOSURE_BSDF_BSSRDF_ID || type == CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID) +#define CLOSURE_IS_BSDF_SINGULAR(type) (type == CLOSURE_BSDF_REFLECTION_ID || \ + type == CLOSURE_BSDF_REFRACTION_ID || \ + type == CLOSURE_BSDF_TRANSPARENT_ID) #define CLOSURE_IS_BSDF_TRANSPARENT(type) (type == CLOSURE_BSDF_TRANSPARENT_ID) -#define CLOSURE_IS_BSDF_ANISOTROPIC(type) (type >= CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID) #define CLOSURE_IS_BSDF_MULTISCATTER(type) (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID ||\ type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID || \ type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) -#define CLOSURE_IS_BSDF_MICROFACET(type) ((type >= CLOSURE_BSDF_REFLECTION_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID) ||\ - (type >= CLOSURE_BSDF_REFRACTION_ID && type <= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID)) +#define CLOSURE_IS_BSDF_MICROFACET(type) ((type >= CLOSURE_BSDF_MICROFACET_GGX_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID) ||\ + (type >= CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID && type <= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) ||\ + (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID)) #define CLOSURE_IS_BSDF_OR_BSSRDF(type) (type <= CLOSURE_BSSRDF_BURLEY_ID) #define CLOSURE_IS_BSSRDF(type) (type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_BURLEY_ID) #define CLOSURE_IS_VOLUME(type) (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index fb04d49bcd9..39ce6a93982 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -518,6 +518,11 @@ ccl_device float safe_modulo(float a, float b) return (b != 0.0f)? fmodf(a, b): 0.0f; } +ccl_device_inline float sqr(float a) +{ + return a * a; +} + ccl_device_inline float beta(float x, float y) { #ifndef __KERNEL_OPENCL__