diff options
-rw-r--r-- | .clang-format | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/closure/alloc.h | 30 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/CMakeLists.txt | 8 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/background.cpp | 77 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp | 68 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/bsdf_phong_ramp.cpp | 69 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/bssrdf.cpp | 105 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/closures.cpp | 1001 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/closures.h | 142 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/closures_setup.h | 1166 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/closures_template.h | 258 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/emissive.cpp | 54 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/services.cpp | 13 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/services.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/shader.cpp | 108 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/shader.h | 3 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/types.h | 21 | ||||
-rw-r--r-- | intern/cycles/scene/osl.cpp | 2 |
18 files changed, 1542 insertions, 1589 deletions
diff --git a/.clang-format b/.clang-format index 7e88e6d1cb1..72add4594a4 100644 --- a/.clang-format +++ b/.clang-format @@ -273,5 +273,5 @@ StatementMacros: - PyObject_VAR_HEAD - ccl_gpu_kernel_postfix -MacroBlockBegin: "^BSDF_CLOSURE_CLASS_BEGIN$" -MacroBlockEnd: "^BSDF_CLOSURE_CLASS_END$" +MacroBlockBegin: "^OSL_CLOSURE_STRUCT_BEGIN$" +MacroBlockEnd: "^OSL_CLOSURE_STRUCT_END$" diff --git a/intern/cycles/kernel/closure/alloc.h b/intern/cycles/kernel/closure/alloc.h index 9847898ee89..1cf06614f3b 100644 --- a/intern/cycles/kernel/closure/alloc.h +++ b/intern/cycles/kernel/closure/alloc.h @@ -59,39 +59,10 @@ ccl_device_inline ccl_private ShaderClosure *bsdf_alloc(ccl_private ShaderData * * we will not allocate new closure. */ if (sample_weight >= CLOSURE_WEIGHT_CUTOFF) { ccl_private ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight); - if (sc == NULL) { - return NULL; - } - - sc->sample_weight = sample_weight; - - return sc; - } - - return NULL; -} - -#ifdef __OSL__ -ccl_device_inline ShaderClosure *bsdf_alloc_osl(ShaderData *sd, - int size, - Spectrum weight, - void *data) -{ - kernel_assert(isfinite_safe(weight)); - - const float sample_weight = fabsf(average(weight)); - - /* Use comparison this way to help dealing with non-finite weight: if the average is not finite - * we will not allocate new closure. */ - if (sample_weight >= CLOSURE_WEIGHT_CUTOFF) { - ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight); if (!sc) { return NULL; } - memcpy((void *)sc, data, size); - - sc->weight = weight; sc->sample_weight = sample_weight; return sc; @@ -99,6 +70,5 @@ ccl_device_inline ShaderClosure *bsdf_alloc_osl(ShaderData *sd, return NULL; } -#endif CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/CMakeLists.txt b/intern/cycles/kernel/osl/CMakeLists.txt index 7570490be7c..b27bcb066fd 100644 --- a/intern/cycles/kernel/osl/CMakeLists.txt +++ b/intern/cycles/kernel/osl/CMakeLists.txt @@ -10,18 +10,14 @@ set(INC_SYS ) set(SRC - background.cpp - bsdf_diffuse_ramp.cpp - bsdf_phong_ramp.cpp - emissive.cpp - bssrdf.cpp closures.cpp services.cpp shader.cpp ) set(HEADER_SRC - closures.h + closures_setup.h + closures_template.h globals.h services.h shader.h diff --git a/intern/cycles/kernel/osl/background.cpp b/intern/cycles/kernel/osl/background.cpp deleted file mode 100644 index 4b5a2686117..00000000000 --- a/intern/cycles/kernel/osl/background.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Adapted from Open Shading Language - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011-2022 Blender Foundation. */ - -#include <OpenImageIO/fmath.h> - -#include <OSL/genclosure.h> - -#include "kernel/osl/closures.h" - -// clang-format off -#include "kernel/device/cpu/compat.h" -#include "kernel/device/cpu/globals.h" - -#include "kernel/closure/alloc.h" -#include "kernel/closure/emissive.h" - -#include "kernel/util/color.h" -// clang-format on - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -/// Generic background closure -/// -/// We only have a background closure for the shaders -/// to return a color in background shaders. No methods, -/// only the weight is taking into account -/// -class GenericBackgroundClosure : public CClosurePrimitive { - public: - void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight) - { - background_setup(sd, rgb_to_spectrum(weight)); - } -}; - -/// Holdout closure -/// -/// This will be used by the shader to mark the -/// amount of holdout for the current shading -/// point. No parameters, only the weight will be -/// used -/// -class HoldoutClosure : CClosurePrimitive { - public: - void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight) - { - closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, rgb_to_spectrum(weight)); - sd->flag |= SD_HOLDOUT; - } -}; - -ClosureParam *closure_background_params() -{ - static ClosureParam params[] = { - CLOSURE_STRING_KEYPARAM(GenericBackgroundClosure, label, "label"), - CLOSURE_FINISH_PARAM(GenericBackgroundClosure)}; - return params; -} - -CCLOSURE_PREPARE(closure_background_prepare, GenericBackgroundClosure) - -ClosureParam *closure_holdout_params() -{ - static ClosureParam params[] = {CLOSURE_FINISH_PARAM(HoldoutClosure)}; - return params; -} - -CCLOSURE_PREPARE(closure_holdout_prepare, HoldoutClosure) - -CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp deleted file mode 100644 index 667207ec6bf..00000000000 --- a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Adapted from Open Shading Language - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011-2022 Blender Foundation. */ - -#include <OpenImageIO/fmath.h> - -#include <OSL/genclosure.h> - -#include "kernel/device/cpu/compat.h" -#include "kernel/osl/closures.h" - -// clang-format off -#include "kernel/device/cpu/compat.h" -#include "kernel/device/cpu/globals.h" - -#include "kernel/types.h" -#include "kernel/closure/alloc.h" -#include "kernel/closure/bsdf_diffuse_ramp.h" -#include "kernel/closure/bsdf_util.h" - -#include "kernel/util/color.h" -// clang-format on - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -class DiffuseRampClosure : public CBSDFClosure { - public: - DiffuseRampBsdf params; - Color3 colors[8]; - - void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - DiffuseRampBsdf *bsdf = (DiffuseRampBsdf *)bsdf_alloc_osl( - sd, sizeof(DiffuseRampBsdf), rgb_to_spectrum(weight), ¶ms); - - if (bsdf) { - bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8); - - if (bsdf->colors) { - for (int i = 0; i < 8; i++) - bsdf->colors[i] = TO_FLOAT3(colors[i]); - - sd->flag |= bsdf_diffuse_ramp_setup(bsdf); - } - } - } -}; - -ClosureParam *closure_bsdf_diffuse_ramp_params() -{ - static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(DiffuseRampClosure, params.N), - CLOSURE_COLOR_ARRAY_PARAM(DiffuseRampClosure, colors, 8), - CLOSURE_STRING_KEYPARAM(DiffuseRampClosure, label, "label"), - CLOSURE_FINISH_PARAM(DiffuseRampClosure)}; - return params; -} - -CCLOSURE_PREPARE(closure_bsdf_diffuse_ramp_prepare, DiffuseRampClosure) - -CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp deleted file mode 100644 index 6f54a96e542..00000000000 --- a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Adapted from Open Shading Language - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011-2022 Blender Foundation. */ - -#include <OpenImageIO/fmath.h> - -#include <OSL/genclosure.h> - -#include "kernel/device/cpu/compat.h" -#include "kernel/osl/closures.h" - -// clang-format off -#include "kernel/device/cpu/compat.h" -#include "kernel/device/cpu/globals.h" - -#include "kernel/types.h" -#include "kernel/closure/alloc.h" -#include "kernel/closure/bsdf_phong_ramp.h" -#include "kernel/closure/bsdf_util.h" - -#include "kernel/util/color.h" -// clang-format on - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -class PhongRampClosure : public CBSDFClosure { - public: - PhongRampBsdf params; - Color3 colors[8]; - - void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - PhongRampBsdf *bsdf = (PhongRampBsdf *)bsdf_alloc_osl( - sd, sizeof(PhongRampBsdf), rgb_to_spectrum(weight), ¶ms); - - if (bsdf) { - bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8); - - if (bsdf->colors) { - for (int i = 0; i < 8; i++) - bsdf->colors[i] = TO_FLOAT3(colors[i]); - - sd->flag |= bsdf_phong_ramp_setup(bsdf); - } - } - } -}; - -ClosureParam *closure_bsdf_phong_ramp_params() -{ - static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(PhongRampClosure, params.N), - CLOSURE_FLOAT_PARAM(PhongRampClosure, params.exponent), - CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, colors, 8), - CLOSURE_STRING_KEYPARAM(PhongRampClosure, label, "label"), - CLOSURE_FINISH_PARAM(PhongRampClosure)}; - return params; -} - -CCLOSURE_PREPARE(closure_bsdf_phong_ramp_prepare, PhongRampClosure) - -CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/bssrdf.cpp b/intern/cycles/kernel/osl/bssrdf.cpp deleted file mode 100644 index 3054946ba5a..00000000000 --- a/intern/cycles/kernel/osl/bssrdf.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Adapted from Open Shading Language - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011-2022 Blender Foundation. */ - -#include <OSL/genclosure.h> - -#include "kernel/device/cpu/compat.h" -#include "kernel/osl/closures.h" - -// clang-format off -#include "kernel/device/cpu/compat.h" -#include "kernel/device/cpu/globals.h" - -#include "kernel/types.h" - -#include "kernel/closure/alloc.h" -#include "kernel/closure/bsdf_util.h" -#include "kernel/closure/bsdf_diffuse.h" -#include "kernel/closure/bsdf_principled_diffuse.h" -#include "kernel/closure/bssrdf.h" - -#include "kernel/util/color.h" -// clang-format on - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -static ustring u_burley("burley"); -static ustring u_random_walk_fixed_radius("random_walk_fixed_radius"); -static ustring u_random_walk("random_walk"); - -class CBSSRDFClosure : public CClosurePrimitive { - public: - Bssrdf params; - float ior; - ustring method; - - CBSSRDFClosure() - { - params.roughness = FLT_MAX; - params.anisotropy = 1.0f; - ior = 1.4f; - } - - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - if (method == u_burley) { - alloc(sd, path_flag, weight, CLOSURE_BSSRDF_BURLEY_ID); - } - else if (method == u_random_walk_fixed_radius) { - alloc(sd, path_flag, weight, CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID); - } - else if (method == u_random_walk) { - alloc(sd, path_flag, weight, CLOSURE_BSSRDF_RANDOM_WALK_ID); - } - } - - void alloc(ShaderData *sd, uint32_t path_flag, float3 weight, ClosureType type) - { - Bssrdf *bssrdf = bssrdf_alloc(sd, rgb_to_spectrum(weight)); - - if (bssrdf) { - /* disable in case of diffuse ancestor, can't see it well then and - * adds considerably noise due to probabilities of continuing path - * getting lower and lower */ - if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR) { - params.radius = zero_spectrum(); - } - - /* create one closure per color channel */ - bssrdf->radius = params.radius; - bssrdf->albedo = params.albedo; - bssrdf->N = params.N; - bssrdf->roughness = params.roughness; - bssrdf->anisotropy = clamp(params.anisotropy, 0.0f, 0.9f); - sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type, clamp(ior, 1.01f, 3.8f)); - } - } -}; - -ClosureParam *closure_bssrdf_params() -{ - static ClosureParam params[] = { - CLOSURE_STRING_PARAM(CBSSRDFClosure, method), - CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.N), - CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.radius), - CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.albedo), - CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, params.roughness, "roughness"), - CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, ior, "ior"), - CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, params.anisotropy, "anisotropy"), - CLOSURE_STRING_KEYPARAM(CBSSRDFClosure, label, "label"), - CLOSURE_FINISH_PARAM(CBSSRDFClosure)}; - return params; -} - -CCLOSURE_PREPARE(closure_bssrdf_prepare, CBSSRDFClosure) - -CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/closures.cpp b/intern/cycles/kernel/osl/closures.cpp index 8766fb73dbb..604d672063b 100644 --- a/intern/cycles/kernel/osl/closures.cpp +++ b/intern/cycles/kernel/osl/closures.cpp @@ -9,999 +9,48 @@ #include <OSL/genclosure.h> #include <OSL/oslclosure.h> -#include "kernel/osl/closures.h" -#include "kernel/osl/shader.h" +#include "kernel/types.h" + +#include "kernel/osl/globals.h" +#include "kernel/osl/services.h" #include "util/math.h" #include "util/param.h" -// clang-format off #include "kernel/device/cpu/compat.h" #include "kernel/device/cpu/globals.h" -#include "kernel/types.h" - -#include "kernel/closure/alloc.h" -#include "kernel/closure/bsdf_util.h" -#include "kernel/closure/bsdf_ashikhmin_velvet.h" -#include "kernel/closure/bsdf_diffuse.h" -#include "kernel/closure/bsdf_microfacet.h" -#include "kernel/closure/bsdf_microfacet_multi.h" -#include "kernel/closure/bsdf_oren_nayar.h" -#include "kernel/closure/bsdf_reflection.h" -#include "kernel/closure/bsdf_refraction.h" -#include "kernel/closure/bsdf_transparent.h" -#include "kernel/closure/bsdf_ashikhmin_shirley.h" -#include "kernel/closure/bsdf_toon.h" -#include "kernel/closure/bsdf_hair.h" -#include "kernel/closure/bsdf_hair_principled.h" -#include "kernel/closure/bsdf_principled_diffuse.h" -#include "kernel/closure/bsdf_principled_sheen.h" -#include "kernel/closure/volume.h" - -#include "kernel/util/color.h" -// clang-format on +#include "kernel/osl/types.h" +#include "kernel/osl/closures_setup.h" CCL_NAMESPACE_BEGIN -using namespace OSL; - -/* BSDF class definitions */ - -BSDF_CLOSURE_CLASS_BEGIN(Diffuse, diffuse, DiffuseBsdf, LABEL_DIFFUSE) - BSDF_CLOSURE_FLOAT3_PARAM(DiffuseClosure, params.N) -BSDF_CLOSURE_CLASS_END(Diffuse, diffuse) - -BSDF_CLOSURE_CLASS_BEGIN(Translucent, translucent, DiffuseBsdf, LABEL_DIFFUSE) - BSDF_CLOSURE_FLOAT3_PARAM(TranslucentClosure, params.N) -BSDF_CLOSURE_CLASS_END(Translucent, translucent) - -BSDF_CLOSURE_CLASS_BEGIN(OrenNayar, oren_nayar, OrenNayarBsdf, LABEL_DIFFUSE) - BSDF_CLOSURE_FLOAT3_PARAM(OrenNayarClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(OrenNayarClosure, params.roughness) -BSDF_CLOSURE_CLASS_END(OrenNayar, oren_nayar) - -BSDF_CLOSURE_CLASS_BEGIN(Reflection, reflection, MicrofacetBsdf, LABEL_SINGULAR) - BSDF_CLOSURE_FLOAT3_PARAM(ReflectionClosure, params.N) -BSDF_CLOSURE_CLASS_END(Reflection, reflection) - -BSDF_CLOSURE_CLASS_BEGIN(Refraction, refraction, MicrofacetBsdf, LABEL_SINGULAR) - BSDF_CLOSURE_FLOAT3_PARAM(RefractionClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(RefractionClosure, params.ior) -BSDF_CLOSURE_CLASS_END(Refraction, refraction) - -BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, VelvetBsdf, LABEL_DIFFUSE) - BSDF_CLOSURE_FLOAT3_PARAM(AshikhminVelvetClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, params.sigma) -BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet) - -BSDF_CLOSURE_CLASS_BEGIN(AshikhminShirley, - ashikhmin_shirley, - MicrofacetBsdf, - LABEL_GLOSSY | LABEL_REFLECT) - BSDF_CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.N) - BSDF_CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.T) - BSDF_CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_x) - BSDF_CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_y) -BSDF_CLOSURE_CLASS_END(AshikhminShirley, ashikhmin_shirley) - -BSDF_CLOSURE_CLASS_BEGIN(DiffuseToon, diffuse_toon, ToonBsdf, LABEL_DIFFUSE) - BSDF_CLOSURE_FLOAT3_PARAM(DiffuseToonClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(DiffuseToonClosure, params.size) - BSDF_CLOSURE_FLOAT_PARAM(DiffuseToonClosure, params.smooth) -BSDF_CLOSURE_CLASS_END(DiffuseToon, diffuse_toon) - -BSDF_CLOSURE_CLASS_BEGIN(GlossyToon, glossy_toon, ToonBsdf, LABEL_GLOSSY) - BSDF_CLOSURE_FLOAT3_PARAM(GlossyToonClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(GlossyToonClosure, params.size) - BSDF_CLOSURE_FLOAT_PARAM(GlossyToonClosure, params.smooth) -BSDF_CLOSURE_CLASS_END(GlossyToon, glossy_toon) - -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXIsotropic, - microfacet_ggx_isotropic, - MicrofacetBsdf, - LABEL_GLOSSY | LABEL_REFLECT) - BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetGGXIsotropicClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetGGXIsotropicClosure, params.alpha_x) -BSDF_CLOSURE_CLASS_END(MicrofacetGGXIsotropic, microfacet_ggx_isotropic) - -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX, - microfacet_ggx, - MicrofacetBsdf, - LABEL_GLOSSY | LABEL_REFLECT) - BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, params.N) - BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, params.T) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, params.alpha_x) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, params.alpha_y) -BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx) - -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannIsotropic, - microfacet_beckmann_isotropic, - MicrofacetBsdf, - LABEL_GLOSSY | LABEL_REFLECT) - BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannIsotropicClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetBeckmannIsotropicClosure, params.alpha_x) -BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannIsotropic, microfacet_beckmann_isotropic) - -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann, - microfacet_beckmann, - MicrofacetBsdf, - LABEL_GLOSSY | LABEL_REFLECT) - BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, params.N) - BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, params.T) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, params.alpha_x) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, params.alpha_y) -BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann) - -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction, - microfacet_ggx_refraction, - MicrofacetBsdf, - LABEL_GLOSSY | LABEL_TRANSMIT) - BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetGGXRefractionClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, params.alpha_x) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, params.ior) -BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction) - -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction, - microfacet_beckmann_refraction, - MicrofacetBsdf, - LABEL_GLOSSY | LABEL_TRANSMIT) - BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannRefractionClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, params.alpha_x) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, params.ior) -BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction) - -BSDF_CLOSURE_CLASS_BEGIN(HairReflection, hair_reflection, HairBsdf, LABEL_GLOSSY) - BSDF_CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.roughness1) - BSDF_CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.roughness2) - BSDF_CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.T) - BSDF_CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.offset) -BSDF_CLOSURE_CLASS_END(HairReflection, hair_reflection) - -BSDF_CLOSURE_CLASS_BEGIN(HairTransmission, hair_transmission, HairBsdf, LABEL_GLOSSY) - BSDF_CLOSURE_FLOAT3_PARAM(HairTransmissionClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(HairTransmissionClosure, params.roughness1) - BSDF_CLOSURE_FLOAT_PARAM(HairTransmissionClosure, params.roughness2) - BSDF_CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.T) - BSDF_CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.offset) -BSDF_CLOSURE_CLASS_END(HairTransmission, hair_transmission) - -BSDF_CLOSURE_CLASS_BEGIN(PrincipledDiffuse, - principled_diffuse, - PrincipledDiffuseBsdf, - LABEL_DIFFUSE) - BSDF_CLOSURE_FLOAT3_PARAM(PrincipledDiffuseClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(PrincipledDiffuseClosure, params.roughness) -BSDF_CLOSURE_CLASS_END(PrincipledDiffuse, principled_diffuse) - -class PrincipledSheenClosure : public CBSDFClosure { - public: - PrincipledSheenBsdf params; - - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - if (!skip(sd, path_flag, LABEL_DIFFUSE)) { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - PrincipledSheenBsdf *bsdf = (PrincipledSheenBsdf *)bsdf_alloc_osl( - sd, sizeof(PrincipledSheenBsdf), rgb_to_spectrum(weight), ¶ms); - sd->flag |= (bsdf) ? bsdf_principled_sheen_setup(sd, bsdf) : 0; - } - } -}; - -static ClosureParam *bsdf_principled_sheen_params() -{ - static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(PrincipledSheenClosure, params.N), - CLOSURE_STRING_KEYPARAM(PrincipledSheenClosure, label, "label"), - CLOSURE_FINISH_PARAM(PrincipledSheenClosure)}; - return params; -} - -CCLOSURE_PREPARE_STATIC(closure_bsdf_principled_sheen_prepare, PrincipledSheenClosure) - -/* PRINCIPLED HAIR BSDF */ -class PrincipledHairClosure : public CBSDFClosure { - public: - PrincipledHairBSDF params; - - PrincipledHairBSDF *alloc(ShaderData *sd, uint32_t path_flag, float3 weight) - { - PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)bsdf_alloc_osl( - sd, sizeof(PrincipledHairBSDF), rgb_to_spectrum(weight), ¶ms); - if (!bsdf) { - return NULL; - } - - PrincipledHairExtra *extra = (PrincipledHairExtra *)closure_alloc_extra( - sd, sizeof(PrincipledHairExtra)); - if (!extra) { - return NULL; - } - - bsdf->extra = extra; - return bsdf; - } - - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - if (!skip(sd, path_flag, LABEL_GLOSSY)) { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - sd->flag |= (bsdf) ? bsdf_principled_hair_setup(sd, bsdf) : 0; - } - } -}; - -static ClosureParam *closure_bsdf_principled_hair_params() -{ - static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(PrincipledHairClosure, params.N), - CLOSURE_FLOAT3_PARAM(PrincipledHairClosure, params.sigma), - CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.v), - CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.s), - CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.m0_roughness), - CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.alpha), - CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.eta), - CLOSURE_STRING_KEYPARAM(PrincipledHairClosure, label, "label"), - CLOSURE_FINISH_PARAM(PrincipledHairClosure)}; - - return params; -} - -CCLOSURE_PREPARE(closure_bsdf_principled_hair_prepare, PrincipledHairClosure) - -/* DISNEY PRINCIPLED CLEARCOAT */ -class PrincipledClearcoatClosure : public CBSDFClosure { - public: - MicrofacetBsdf params; - float clearcoat, clearcoat_roughness; - - MicrofacetBsdf *alloc(ShaderData *sd, uint32_t path_flag, float3 weight) - { - MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), ¶ms); - if (!bsdf) { - return NULL; - } - - MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); - if (!extra) { - return NULL; - } - - bsdf->T = zero_float3(); - bsdf->extra = extra; - bsdf->ior = 1.5f; - bsdf->alpha_x = clearcoat_roughness; - bsdf->alpha_y = clearcoat_roughness; - bsdf->extra->color = zero_spectrum(); - bsdf->extra->cspec0 = make_spectrum(0.04f); - bsdf->extra->clearcoat = clearcoat; - return bsdf; - } - - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd); - } -}; - -ClosureParam *closure_bsdf_principled_clearcoat_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT3_PARAM(PrincipledClearcoatClosure, params.N), - CLOSURE_FLOAT_PARAM(PrincipledClearcoatClosure, clearcoat), - CLOSURE_FLOAT_PARAM(PrincipledClearcoatClosure, clearcoat_roughness), - CLOSURE_STRING_KEYPARAM(PrincipledClearcoatClosure, label, "label"), - CLOSURE_FINISH_PARAM(PrincipledClearcoatClosure)}; - return params; -} -CCLOSURE_PREPARE(closure_bsdf_principled_clearcoat_prepare, PrincipledClearcoatClosure) - /* Registration */ -static void register_closure(OSL::ShadingSystem *ss, - const char *name, - int id, - OSL::ClosureParam *params, - OSL::PrepareClosureFunc prepare) -{ - /* optimization: it's possible to not use a prepare function at all and - * only initialize the actual class when accessing the closure component - * data, but then we need to map the id to the class somehow */ -#if OSL_LIBRARY_VERSION_CODE >= 10900 - ss->register_closure(name, id, params, prepare, NULL); -#else - ss->register_closure(name, id, params, prepare, NULL, 16); -#endif -} - -void OSLShader::register_closures(OSLShadingSystem *ss_) -{ - OSL::ShadingSystem *ss = (OSL::ShadingSystem *)ss_; - int id = 0; - - register_closure(ss, "diffuse", id++, bsdf_diffuse_params(), bsdf_diffuse_prepare); - register_closure(ss, "oren_nayar", id++, bsdf_oren_nayar_params(), bsdf_oren_nayar_prepare); - register_closure(ss, "translucent", id++, bsdf_translucent_params(), bsdf_translucent_prepare); - register_closure(ss, "reflection", id++, bsdf_reflection_params(), bsdf_reflection_prepare); - register_closure(ss, "refraction", id++, bsdf_refraction_params(), bsdf_refraction_prepare); - register_closure(ss, - "transparent", - id++, - closure_bsdf_transparent_params(), - closure_bsdf_transparent_prepare); - - register_closure( - ss, "microfacet", id++, closure_bsdf_microfacet_params(), closure_bsdf_microfacet_prepare); - register_closure(ss, - "microfacet_ggx", - id++, - bsdf_microfacet_ggx_isotropic_params(), - bsdf_microfacet_ggx_isotropic_prepare); - register_closure( - ss, "microfacet_ggx_aniso", id++, bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare); - register_closure(ss, - "microfacet_ggx_refraction", - id++, - bsdf_microfacet_ggx_refraction_params(), - bsdf_microfacet_ggx_refraction_prepare); - register_closure(ss, - "microfacet_multi_ggx", - id++, - closure_bsdf_microfacet_multi_ggx_params(), - closure_bsdf_microfacet_multi_ggx_prepare); - register_closure(ss, - "microfacet_multi_ggx_glass", - id++, - closure_bsdf_microfacet_multi_ggx_glass_params(), - closure_bsdf_microfacet_multi_ggx_glass_prepare); - register_closure(ss, - "microfacet_multi_ggx_aniso", - id++, - closure_bsdf_microfacet_multi_ggx_aniso_params(), - closure_bsdf_microfacet_multi_ggx_aniso_prepare); - register_closure(ss, - "microfacet_ggx_fresnel", - id++, - closure_bsdf_microfacet_ggx_fresnel_params(), - closure_bsdf_microfacet_ggx_fresnel_prepare); - register_closure(ss, - "microfacet_ggx_aniso_fresnel", - id++, - closure_bsdf_microfacet_ggx_aniso_fresnel_params(), - closure_bsdf_microfacet_ggx_aniso_fresnel_prepare); - register_closure(ss, - "microfacet_multi_ggx_fresnel", - id++, - closure_bsdf_microfacet_multi_ggx_fresnel_params(), - closure_bsdf_microfacet_multi_ggx_fresnel_prepare); - register_closure(ss, - "microfacet_multi_ggx_glass_fresnel", - id++, - closure_bsdf_microfacet_multi_ggx_glass_fresnel_params(), - closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare); - register_closure(ss, - "microfacet_multi_ggx_aniso_fresnel", - id++, - closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params(), - closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare); - register_closure(ss, - "microfacet_beckmann", - id++, - bsdf_microfacet_beckmann_isotropic_params(), - bsdf_microfacet_beckmann_isotropic_prepare); - register_closure(ss, - "microfacet_beckmann_aniso", - id++, - bsdf_microfacet_beckmann_params(), - bsdf_microfacet_beckmann_prepare); - register_closure(ss, - "microfacet_beckmann_refraction", - id++, - bsdf_microfacet_beckmann_refraction_params(), - bsdf_microfacet_beckmann_refraction_prepare); - register_closure(ss, - "ashikhmin_shirley", - id++, - bsdf_ashikhmin_shirley_params(), - bsdf_ashikhmin_shirley_prepare); - register_closure( - ss, "ashikhmin_velvet", id++, bsdf_ashikhmin_velvet_params(), bsdf_ashikhmin_velvet_prepare); - register_closure( - ss, "diffuse_toon", id++, bsdf_diffuse_toon_params(), bsdf_diffuse_toon_prepare); - register_closure(ss, "glossy_toon", id++, bsdf_glossy_toon_params(), bsdf_glossy_toon_prepare); - register_closure(ss, - "principled_diffuse", - id++, - bsdf_principled_diffuse_params(), - bsdf_principled_diffuse_prepare); - register_closure(ss, - "principled_sheen", - id++, - bsdf_principled_sheen_params(), - closure_bsdf_principled_sheen_prepare); - register_closure(ss, - "principled_clearcoat", - id++, - closure_bsdf_principled_clearcoat_params(), - closure_bsdf_principled_clearcoat_prepare); - - register_closure(ss, "emission", id++, closure_emission_params(), closure_emission_prepare); - register_closure( - ss, "background", id++, closure_background_params(), closure_background_prepare); - register_closure(ss, "holdout", id++, closure_holdout_params(), closure_holdout_prepare); - register_closure(ss, - "diffuse_ramp", - id++, - closure_bsdf_diffuse_ramp_params(), - closure_bsdf_diffuse_ramp_prepare); - register_closure( - ss, "phong_ramp", id++, closure_bsdf_phong_ramp_params(), closure_bsdf_phong_ramp_prepare); - register_closure(ss, "bssrdf", id++, closure_bssrdf_params(), closure_bssrdf_prepare); - - register_closure( - ss, "hair_reflection", id++, bsdf_hair_reflection_params(), bsdf_hair_reflection_prepare); - register_closure(ss, - "hair_transmission", - id++, - bsdf_hair_transmission_params(), - bsdf_hair_transmission_prepare); - - register_closure(ss, - "principled_hair", - id++, - closure_bsdf_principled_hair_params(), - closure_bsdf_principled_hair_prepare); - - register_closure(ss, - "henyey_greenstein", - id++, - closure_henyey_greenstein_params(), - closure_henyey_greenstein_prepare); - register_closure( - ss, "absorption", id++, closure_absorption_params(), closure_absorption_prepare); -} - -/* BSDF Closure */ - -bool CBSDFClosure::skip(const ShaderData *sd, uint32_t path_flag, int scattering) -{ - /* caustic options */ - if ((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) { - const KernelGlobalsCPU *kg = sd->osl_globals; - - if ((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) || - (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) { - return true; - } - } - - return false; -} - -/* Standard Microfacet Closure */ - -class MicrofacetClosure : public CBSDFClosure { - public: - MicrofacetBsdf params; - ustring distribution; - int refract; - - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - static ustring u_ggx("ggx"); - static ustring u_default("default"); - - const int label = (refract) ? LABEL_TRANSMIT : LABEL_REFLECT; - if (skip(sd, path_flag, LABEL_GLOSSY | label)) { - return; - } - - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), ¶ms); - - if (!bsdf) { - return; - } - - /* GGX */ - if (distribution == u_ggx || distribution == u_default) { - if (!refract) { - if (params.alpha_x == params.alpha_y) { - /* Isotropic */ - sd->flag |= bsdf_microfacet_ggx_isotropic_setup(bsdf); - } - else { - /* Anisotropic */ - sd->flag |= bsdf_microfacet_ggx_setup(bsdf); - } - } - else { - sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); - } - } - /* Beckmann */ - else { - if (!refract) { - if (params.alpha_x == params.alpha_y) { - /* Isotropic */ - sd->flag |= bsdf_microfacet_beckmann_isotropic_setup(bsdf); - } - else { - /* Anisotropic */ - sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); - } - } - else { - sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf); - } - } - } -}; - -ClosureParam *closure_bsdf_microfacet_params() -{ - static ClosureParam params[] = {CLOSURE_STRING_PARAM(MicrofacetClosure, distribution), - CLOSURE_FLOAT3_PARAM(MicrofacetClosure, params.N), - CLOSURE_FLOAT3_PARAM(MicrofacetClosure, params.T), - CLOSURE_FLOAT_PARAM(MicrofacetClosure, params.alpha_x), - CLOSURE_FLOAT_PARAM(MicrofacetClosure, params.alpha_y), - CLOSURE_FLOAT_PARAM(MicrofacetClosure, params.ior), - CLOSURE_INT_PARAM(MicrofacetClosure, refract), - CLOSURE_STRING_KEYPARAM(MicrofacetClosure, label, "label"), - CLOSURE_FINISH_PARAM(MicrofacetClosure)}; - - return params; -} -CCLOSURE_PREPARE(closure_bsdf_microfacet_prepare, MicrofacetClosure) - -/* GGX closures with Fresnel */ - -class MicrofacetFresnelClosure : public CBSDFClosure { - public: - MicrofacetBsdf params; - float3 color; - float3 cspec0; - - MicrofacetBsdf *alloc(ShaderData *sd, uint32_t path_flag, float3 weight) - { - /* Technically, the MultiGGX Glass closure may also transmit. However, - * since this is set statically and only used for caustic flags, this - * is probably as good as it gets. */ - if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { - return NULL; - } - - MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), ¶ms); - if (!bsdf) { - return NULL; - } - - MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); - if (!extra) { - return NULL; - } - - bsdf->extra = extra; - bsdf->extra->color = rgb_to_spectrum(color); - bsdf->extra->cspec0 = rgb_to_spectrum(cspec0); - bsdf->extra->clearcoat = 0.0f; - return bsdf; - } -}; - -class MicrofacetGGXFresnelClosure : public MicrofacetFresnelClosure { - public: - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - bsdf->T = zero_float3(); - bsdf->alpha_y = bsdf->alpha_x; - sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd); - } -}; - -ClosureParam *closure_bsdf_microfacet_ggx_fresnel_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.N), - CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_x), - CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.ior), - CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, color), - CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, cspec0), - CLOSURE_STRING_KEYPARAM(MicrofacetGGXFresnelClosure, label, "label"), - CLOSURE_FINISH_PARAM(MicrofacetGGXFresnelClosure)}; - return params; -} -CCLOSURE_PREPARE(closure_bsdf_microfacet_ggx_fresnel_prepare, MicrofacetGGXFresnelClosure); - -class MicrofacetGGXAnisoFresnelClosure : public MicrofacetFresnelClosure { - public: - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd); - } -}; - -ClosureParam *closure_bsdf_microfacet_ggx_aniso_fresnel_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.N), - CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.T), - CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_x), - CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_y), - CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.ior), - CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, color), - CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, cspec0), - CLOSURE_STRING_KEYPARAM(MicrofacetGGXFresnelClosure, label, "label"), - CLOSURE_FINISH_PARAM(MicrofacetGGXFresnelClosure)}; - return params; -} -CCLOSURE_PREPARE(closure_bsdf_microfacet_ggx_aniso_fresnel_prepare, - MicrofacetGGXAnisoFresnelClosure); - -/* Multiscattering GGX closures */ - -class MicrofacetMultiClosure : public CBSDFClosure { - public: - MicrofacetBsdf params; - float3 color; - - MicrofacetBsdf *alloc(ShaderData *sd, uint32_t path_flag, float3 weight) - { - /* Technically, the MultiGGX closure may also transmit. However, - * since this is set statically and only used for caustic flags, this - * is probably as good as it gets. */ - if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { - return NULL; - } - - MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), ¶ms); - if (!bsdf) { - return NULL; - } - - MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); - if (!extra) { - return NULL; - } - - bsdf->extra = extra; - bsdf->extra->color = rgb_to_spectrum(color); - bsdf->extra->cspec0 = zero_spectrum(); - bsdf->extra->clearcoat = 0.0f; - return bsdf; - } -}; - -class MicrofacetMultiGGXClosure : public MicrofacetMultiClosure { - public: - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - bsdf->ior = 0.0f; - bsdf->T = zero_float3(); - bsdf->alpha_y = bsdf->alpha_x; - sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf); - } -}; - -ClosureParam *closure_bsdf_microfacet_multi_ggx_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color), - CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"), - CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)}; - return params; -} -CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_prepare, MicrofacetMultiGGXClosure); - -class MicrofacetMultiGGXAnisoClosure : public MicrofacetMultiClosure { - public: - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - bsdf->ior = 0.0f; - sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf); - } -}; - -ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.T), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_y), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color), - CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"), - CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)}; - return params; -} -CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_aniso_prepare, MicrofacetMultiGGXAnisoClosure); - -class MicrofacetMultiGGXGlassClosure : public MicrofacetMultiClosure { - public: - MicrofacetMultiGGXGlassClosure() : MicrofacetMultiClosure() - { - } - - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - bsdf->T = zero_float3(); - bsdf->alpha_y = bsdf->alpha_x; - sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf); - } -}; - -ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.ior), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color), - CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"), - CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)}; - return params; -} -CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_glass_prepare, MicrofacetMultiGGXGlassClosure); - -/* Multiscattering GGX closures with Fresnel */ - -class MicrofacetMultiFresnelClosure : public CBSDFClosure { - public: - MicrofacetBsdf params; - float3 color; - float3 cspec0; - - MicrofacetBsdf *alloc(ShaderData *sd, uint32_t path_flag, float3 weight) - { - /* Technically, the MultiGGX closure may also transmit. However, - * since this is set statically and only used for caustic flags, this - * is probably as good as it gets. */ - if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { - return NULL; - } - - MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), ¶ms); - if (!bsdf) { - return NULL; - } - - MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); - if (!extra) { - return NULL; - } - - bsdf->extra = extra; - bsdf->extra->color = rgb_to_spectrum(color); - bsdf->extra->cspec0 = rgb_to_spectrum(cspec0); - bsdf->extra->clearcoat = 0.0f; - return bsdf; - } -}; - -class MicrofacetMultiGGXFresnelClosure : public MicrofacetMultiFresnelClosure { - public: - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - bsdf->T = zero_float3(); - bsdf->alpha_y = bsdf->alpha_x; - sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd); +#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \ + static OSL::ClosureParam *osl_closure_##lower##_params() \ + { \ + static OSL::ClosureParam params[] = { +#define OSL_CLOSURE_STRUCT_END(Upper, lower) \ + CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), CLOSURE_FINISH_PARAM(Upper##Closure) \ + } \ + ; \ + return params; \ } -}; - -ClosureParam *closure_bsdf_microfacet_multi_ggx_fresnel_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0), - CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"), - CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)}; - return params; -} -CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_fresnel_prepare, - MicrofacetMultiGGXFresnelClosure); +#define OSL_CLOSURE_STRUCT_MEMBER(Upper, TYPE, type, name, key) \ + CLOSURE_##TYPE##_KEYPARAM(Upper##Closure, name, key), +#define OSL_CLOSURE_STRUCT_ARRAY_MEMBER(Upper, TYPE, type, name, key, size) \ + CLOSURE_##TYPE##_ARRAY_PARAM(Upper##Closure, name, size), -class MicrofacetMultiGGXAnisoFresnelClosure : public MicrofacetMultiFresnelClosure { - public: - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); +#include "closures_template.h" - MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd); - } -}; - -ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params() +void OSLRenderServices::register_closures(OSL::ShadingSystem *ss) { - static ClosureParam params[] = { - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.T), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_y), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0), - CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"), - CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)}; - return params; -} -CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare, - MicrofacetMultiGGXAnisoFresnelClosure); - -class MicrofacetMultiGGXGlassFresnelClosure : public MicrofacetMultiFresnelClosure { - public: - MicrofacetMultiGGXGlassFresnelClosure() : MicrofacetMultiFresnelClosure() - { - } +#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \ + ss->register_closure( \ + #lower, OSL_CLOSURE_##Upper##_ID, osl_closure_##lower##_params(), nullptr, nullptr); - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - bsdf->T = zero_float3(); - bsdf->alpha_y = bsdf->alpha_x; - sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd); - } -}; - -ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_fresnel_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0), - CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"), - CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)}; - return params; +#include "closures_template.h" } -CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare, - MicrofacetMultiGGXGlassFresnelClosure); - -/* Transparent */ - -class TransparentClosure : public CBSDFClosure { - public: - ShaderClosure params; - float3 unused; - - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - bsdf_transparent_setup(sd, rgb_to_spectrum(weight), path_flag); - } -}; - -ClosureParam *closure_bsdf_transparent_params() -{ - static ClosureParam params[] = {CLOSURE_STRING_KEYPARAM(TransparentClosure, label, "label"), - CLOSURE_FINISH_PARAM(TransparentClosure)}; - return params; -} - -CCLOSURE_PREPARE(closure_bsdf_transparent_prepare, TransparentClosure) - -/* Volume */ - -class VolumeAbsorptionClosure : public CBSDFClosure { - public: - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - volume_extinction_setup(sd, rgb_to_spectrum(weight)); - } -}; - -ClosureParam *closure_absorption_params() -{ - static ClosureParam params[] = {CLOSURE_STRING_KEYPARAM(VolumeAbsorptionClosure, label, "label"), - CLOSURE_FINISH_PARAM(VolumeAbsorptionClosure)}; - return params; -} - -CCLOSURE_PREPARE(closure_absorption_prepare, VolumeAbsorptionClosure) - -class VolumeHenyeyGreensteinClosure : public CBSDFClosure { - public: - HenyeyGreensteinVolume params; - - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - volume_extinction_setup(sd, rgb_to_spectrum(weight)); - - HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume *)bsdf_alloc_osl( - sd, sizeof(HenyeyGreensteinVolume), rgb_to_spectrum(weight), ¶ms); - if (!volume) { - return; - } - - sd->flag |= volume_henyey_greenstein_setup(volume); - } -}; - -ClosureParam *closure_henyey_greenstein_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT_PARAM(VolumeHenyeyGreensteinClosure, params.g), - CLOSURE_STRING_KEYPARAM(VolumeHenyeyGreensteinClosure, label, "label"), - CLOSURE_FINISH_PARAM(VolumeHenyeyGreensteinClosure)}; - return params; -} - -CCLOSURE_PREPARE(closure_henyey_greenstein_prepare, VolumeHenyeyGreensteinClosure) CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/closures.h b/intern/cycles/kernel/osl/closures.h deleted file mode 100644 index 97666be7a1e..00000000000 --- a/intern/cycles/kernel/osl/closures.h +++ /dev/null @@ -1,142 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Adapted from Open Shading Language - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011-2022 Blender Foundation. */ - -#ifndef __OSL_CLOSURES_H__ -#define __OSL_CLOSURES_H__ - -#include "kernel/types.h" -#include "util/types.h" - -#include <OSL/genclosure.h> -#include <OSL/oslclosure.h> -#include <OSL/oslexec.h> - -CCL_NAMESPACE_BEGIN - -OSL::ClosureParam *closure_emission_params(); -OSL::ClosureParam *closure_background_params(); -OSL::ClosureParam *closure_holdout_params(); -OSL::ClosureParam *closure_bsdf_diffuse_ramp_params(); -OSL::ClosureParam *closure_bsdf_phong_ramp_params(); -OSL::ClosureParam *closure_bsdf_transparent_params(); -OSL::ClosureParam *closure_bssrdf_params(); -OSL::ClosureParam *closure_absorption_params(); -OSL::ClosureParam *closure_henyey_greenstein_params(); -OSL::ClosureParam *closure_bsdf_microfacet_params(); -OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_params(); -OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_params(); -OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_params(); -OSL::ClosureParam *closure_bsdf_microfacet_ggx_fresnel_params(); -OSL::ClosureParam *closure_bsdf_microfacet_ggx_aniso_fresnel_params(); -OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_fresnel_params(); -OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_fresnel_params(); -OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params(); -OSL::ClosureParam *closure_bsdf_principled_clearcoat_params(); - -void closure_emission_prepare(OSL::RendererServices *, int id, void *data); -void closure_background_prepare(OSL::RendererServices *, int id, void *data); -void closure_holdout_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_diffuse_ramp_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_phong_ramp_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_transparent_prepare(OSL::RendererServices *, int id, void *data); -void closure_bssrdf_prepare(OSL::RendererServices *, int id, void *data); -void closure_absorption_prepare(OSL::RendererServices *, int id, void *data); -void closure_henyey_greenstein_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_microfacet_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_microfacet_multi_ggx_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_microfacet_multi_ggx_glass_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_microfacet_multi_ggx_aniso_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_microfacet_ggx_fresnel_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_microfacet_ggx_aniso_fresnel_prepare(OSL::RendererServices *, - int id, - void *data); -void closure_bsdf_microfacet_multi_ggx_fresnel_prepare(OSL::RendererServices *, - int id, - void *data); -void closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare(OSL::RendererServices *, - int id, - void *data); -void closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare(OSL::RendererServices *, - int id, - void *data); -void closure_bsdf_principled_clearcoat_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_principled_hair_prepare(OSL::RendererServices *, int id, void *data); - -#define CCLOSURE_PREPARE(name, classname) \ - void name(RendererServices *, int id, void *data) \ - { \ - memset(data, 0, sizeof(classname)); \ - new (data) classname(); \ - } - -#define CCLOSURE_PREPARE_STATIC(name, classname) static CCLOSURE_PREPARE(name, classname) - -#define CLOSURE_FLOAT3_PARAM(st, fld) \ - { \ - TypeDesc::TypeVector, (int)reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) \ - } - -#define BSDF_CLOSURE_FLOAT_PARAM(st, fld) CLOSURE_FLOAT_PARAM(st, fld), -#define BSDF_CLOSURE_FLOAT3_PARAM(st, fld) CLOSURE_FLOAT3_PARAM(st, fld), - -#define TO_VEC3(v) OSL::Vec3(v.x, v.y, v.z) -#define TO_COLOR3(v) OSL::Color3(v.x, v.y, v.z) -#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2]) - -/* Closure */ - -class CClosurePrimitive { - public: - virtual void setup(ShaderData *sd, uint32_t path_flag, float3 weight) = 0; - - OSL::ustring label; -}; - -/* BSDF */ - -class CBSDFClosure : public CClosurePrimitive { - public: - bool skip(const ShaderData *sd, uint32_t path_flag, int scattering); -}; - -#define BSDF_CLOSURE_CLASS_BEGIN(Upper, lower, structname, TYPE) \ -\ - class Upper##Closure : public CBSDFClosure { \ - public: \ - structname params; \ - float3 unused; \ -\ - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) \ - { \ - if (!skip(sd, path_flag, TYPE)) { \ - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); \ - structname *bsdf = (structname *)bsdf_alloc_osl( \ - sd, sizeof(structname), rgb_to_spectrum(weight), ¶ms); \ - sd->flag |= (bsdf) ? bsdf_##lower##_setup(bsdf) : 0; \ - } \ - } \ - }; \ -\ - static ClosureParam *bsdf_##lower##_params() \ - { \ - static ClosureParam params[] = { - -/* parameters */ - -#define BSDF_CLOSURE_CLASS_END(Upper, lower) \ - CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), CLOSURE_FINISH_PARAM(Upper##Closure) \ - } \ - ; \ - return params; \ - } \ -\ - CCLOSURE_PREPARE_STATIC(bsdf_##lower##_prepare, Upper##Closure) - -CCL_NAMESPACE_END - -#endif /* __OSL_CLOSURES_H__ */ diff --git a/intern/cycles/kernel/osl/closures_setup.h b/intern/cycles/kernel/osl/closures_setup.h new file mode 100644 index 00000000000..7972bba7d5c --- /dev/null +++ b/intern/cycles/kernel/osl/closures_setup.h @@ -0,0 +1,1166 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Adapted from Open Shading Language + * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. + * All Rights Reserved. + * + * Modifications Copyright 2011-2022 Blender Foundation. */ + +#pragma once + +// clang-format off +#include "kernel/closure/alloc.h" +#include "kernel/closure/bsdf_util.h" +#include "kernel/closure/bsdf_ashikhmin_velvet.h" +#include "kernel/closure/bsdf_diffuse.h" +#include "kernel/closure/bsdf_microfacet.h" +#include "kernel/closure/bsdf_microfacet_multi.h" +#include "kernel/closure/bsdf_oren_nayar.h" +#include "kernel/closure/bsdf_reflection.h" +#include "kernel/closure/bsdf_refraction.h" +#include "kernel/closure/bsdf_transparent.h" +#include "kernel/closure/bsdf_ashikhmin_shirley.h" +#include "kernel/closure/bsdf_toon.h" +#include "kernel/closure/bsdf_hair.h" +#include "kernel/closure/bsdf_hair_principled.h" +#include "kernel/closure/bsdf_principled_diffuse.h" +#include "kernel/closure/bsdf_principled_sheen.h" +#include "kernel/closure/volume.h" +#include "kernel/closure/bsdf_diffuse_ramp.h" +#include "kernel/closure/bsdf_phong_ramp.h" +#include "kernel/closure/bssrdf.h" +#include "kernel/closure/emissive.h" +// clang-format on + +CCL_NAMESPACE_BEGIN + +#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \ + struct ccl_align(8) Upper##Closure \ + { \ + const char *label; +#define OSL_CLOSURE_STRUCT_END(Upper, lower) \ + } \ + ; \ + ccl_device void osl_closure_##lower##_setup(KernelGlobals kg, \ + ccl_private ShaderData *sd, \ + uint32_t path_flag, \ + float3 weight, \ + ccl_private Upper##Closure *closure); +#define OSL_CLOSURE_STRUCT_MEMBER(Upper, TYPE, type, name, key) type name; +#define OSL_CLOSURE_STRUCT_ARRAY_MEMBER(Upper, TYPE, type, name, key, size) type name[size]; + +#include "closures_template.h" + +ccl_device_forceinline bool osl_closure_skip(KernelGlobals kg, + ccl_private const ShaderData *sd, + uint32_t path_flag, + int scattering) +{ + /* caustic options */ + if ((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) { + if ((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) || + (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) { + return true; + } + } + + return false; +} + +/* Diffuse */ + +ccl_device void osl_closure_diffuse_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const DiffuseClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) { + return; + } + + ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc( + sd, sizeof(DiffuseBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + + sd->flag |= bsdf_diffuse_setup(bsdf); +} + +ccl_device void osl_closure_oren_nayar_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const OrenNayarClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) { + return; + } + + ccl_private OrenNayarBsdf *bsdf = (ccl_private OrenNayarBsdf *)bsdf_alloc( + sd, sizeof(OrenNayarBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->roughness = closure->roughness; + + sd->flag |= bsdf_oren_nayar_setup(bsdf); +} + +ccl_device void osl_closure_translucent_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const TranslucentClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) { + return; + } + + ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc( + sd, sizeof(DiffuseBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + + sd->flag |= bsdf_translucent_setup(bsdf); +} + +ccl_device void osl_closure_reflection_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const ReflectionClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_SINGULAR)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + + sd->flag |= bsdf_reflection_setup(bsdf); +} + +ccl_device void osl_closure_refraction_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const RefractionClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_SINGULAR)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->ior = closure->ior; + + sd->flag |= bsdf_refraction_setup(bsdf); +} + +ccl_device void osl_closure_transparent_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const TransparentClosure *closure) +{ + bsdf_transparent_setup(sd, rgb_to_spectrum(weight), path_flag); +} + +/* Standard microfacet closures */ + +ccl_device void osl_closure_microfacet_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetClosure *closure) +{ + const int label = (closure->refract) ? LABEL_TRANSMIT : LABEL_REFLECT; + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | label)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = closure->alpha_y; + bsdf->ior = closure->ior; + bsdf->T = closure->T; + + static OSL::ustring u_ggx("ggx"); + static OSL::ustring u_default("default"); + + /* GGX */ + if (closure->distribution == u_ggx || closure->distribution == u_default) { + if (!closure->refract) { + if (closure->alpha_x == closure->alpha_y) { + /* Isotropic */ + sd->flag |= bsdf_microfacet_ggx_isotropic_setup(bsdf); + } + else { + /* Anisotropic */ + sd->flag |= bsdf_microfacet_ggx_setup(bsdf); + } + } + else { + sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); + } + } + /* Beckmann */ + else { + if (!closure->refract) { + if (closure->alpha_x == closure->alpha_y) { + /* Isotropic */ + sd->flag |= bsdf_microfacet_beckmann_isotropic_setup(bsdf); + } + else { + /* Anisotropic */ + sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); + } + } + else { + sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf); + } + } +} + +ccl_device void osl_closure_microfacet_ggx_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetGGXIsotropicClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + + sd->flag |= bsdf_microfacet_ggx_isotropic_setup(bsdf); +} + +ccl_device void osl_closure_microfacet_ggx_aniso_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetGGXClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = closure->alpha_y; + bsdf->T = closure->T; + + sd->flag |= bsdf_microfacet_ggx_setup(bsdf); +} + +ccl_device void osl_closure_microfacet_ggx_refraction_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetGGXRefractionClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_TRANSMIT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->ior = closure->ior; + + sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); +} + +/* GGX closures with Fresnel */ + +ccl_device void osl_closure_microfacet_ggx_fresnel_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetGGXFresnelClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + ccl_private MicrofacetExtra *extra = (ccl_private MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = bsdf->alpha_x; + bsdf->ior = closure->ior; + + bsdf->extra = extra; + bsdf->extra->color = rgb_to_spectrum(closure->color); + bsdf->extra->cspec0 = rgb_to_spectrum(closure->cspec0); + bsdf->extra->clearcoat = 0.0f; + + bsdf->T = zero_float3(); + + sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd); +} + +ccl_device void osl_closure_microfacet_ggx_aniso_fresnel_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetGGXAnisoFresnelClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + ccl_private MicrofacetExtra *extra = (ccl_private MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = closure->alpha_y; + bsdf->ior = closure->ior; + + bsdf->extra = extra; + bsdf->extra->color = rgb_to_spectrum(closure->color); + bsdf->extra->cspec0 = rgb_to_spectrum(closure->cspec0); + bsdf->extra->clearcoat = 0.0f; + + bsdf->T = closure->T; + + sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd); +} + +/* Multiscattering GGX closures */ + +ccl_device void osl_closure_microfacet_multi_ggx_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetMultiGGXClosure *closure) +{ + /* Technically, the MultiGGX closure may also transmit. However, + * since this is set statically and only used for caustic flags, this + * is probably as good as it gets. */ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + ccl_private MicrofacetExtra *extra = (ccl_private MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = bsdf->alpha_x; + bsdf->ior = 0.0f; + + bsdf->extra = extra; + bsdf->extra->color = rgb_to_spectrum(closure->color); + bsdf->extra->cspec0 = zero_spectrum(); + bsdf->extra->clearcoat = 0.0f; + + bsdf->T = zero_float3(); + + sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf); +} + +ccl_device void osl_closure_microfacet_multi_ggx_glass_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetMultiGGXGlassClosure *closure) +{ + /* Technically, the MultiGGX closure may also transmit. However, + * since this is set statically and only used for caustic flags, this + * is probably as good as it gets. */ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + ccl_private MicrofacetExtra *extra = (ccl_private MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = bsdf->alpha_x; + bsdf->ior = closure->ior; + + bsdf->extra = extra; + bsdf->extra->color = rgb_to_spectrum(closure->color); + bsdf->extra->cspec0 = zero_spectrum(); + bsdf->extra->clearcoat = 0.0f; + + bsdf->T = zero_float3(); + + sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf); +} + +ccl_device void osl_closure_microfacet_multi_ggx_aniso_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetMultiGGXAnisoClosure *closure) +{ + /* Technically, the MultiGGX closure may also transmit. However, + * since this is set statically and only used for caustic flags, this + * is probably as good as it gets. */ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + ccl_private MicrofacetExtra *extra = (ccl_private MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = closure->alpha_y; + bsdf->ior = 0.0f; + + bsdf->extra = extra; + bsdf->extra->color = rgb_to_spectrum(closure->color); + bsdf->extra->cspec0 = zero_spectrum(); + bsdf->extra->clearcoat = 0.0f; + + bsdf->T = closure->T; + + sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf); +} + +/* Multiscattering GGX closures with Fresnel */ + +ccl_device void osl_closure_microfacet_multi_ggx_fresnel_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetMultiGGXFresnelClosure *closure) +{ + /* Technically, the MultiGGX closure may also transmit. However, + * since this is set statically and only used for caustic flags, this + * is probably as good as it gets. */ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + ccl_private MicrofacetExtra *extra = (ccl_private MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = bsdf->alpha_x; + bsdf->ior = closure->ior; + + bsdf->extra = extra; + bsdf->extra->color = rgb_to_spectrum(closure->color); + bsdf->extra->cspec0 = rgb_to_spectrum(closure->cspec0); + bsdf->extra->clearcoat = 0.0f; + + bsdf->T = zero_float3(); + + sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd); +} + +ccl_device void osl_closure_microfacet_multi_ggx_glass_fresnel_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetMultiGGXGlassFresnelClosure *closure) +{ + /* Technically, the MultiGGX closure may also transmit. However, + * since this is set statically and only used for caustic flags, this + * is probably as good as it gets. */ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + ccl_private MicrofacetExtra *extra = (ccl_private MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = bsdf->alpha_x; + bsdf->ior = closure->ior; + + bsdf->extra = extra; + bsdf->extra->color = rgb_to_spectrum(closure->color); + bsdf->extra->cspec0 = rgb_to_spectrum(closure->cspec0); + bsdf->extra->clearcoat = 0.0f; + + bsdf->T = zero_float3(); + + sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd); +} + +ccl_device void osl_closure_microfacet_multi_ggx_aniso_fresnel_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetMultiGGXAnisoFresnelClosure *closure) +{ + /* Technically, the MultiGGX closure may also transmit. However, + * since this is set statically and only used for caustic flags, this + * is probably as good as it gets. */ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + ccl_private MicrofacetExtra *extra = (ccl_private MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = closure->alpha_y; + bsdf->ior = closure->ior; + + bsdf->extra = extra; + bsdf->extra->color = rgb_to_spectrum(closure->color); + bsdf->extra->cspec0 = rgb_to_spectrum(closure->cspec0); + bsdf->extra->clearcoat = 0.0f; + + bsdf->T = closure->T; + + sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd); +} + +/* Beckmann closures */ + +ccl_device void osl_closure_microfacet_beckmann_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetBeckmannIsotropicClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + + sd->flag |= bsdf_microfacet_beckmann_isotropic_setup(bsdf); +} + +ccl_device void osl_closure_microfacet_beckmann_aniso_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetBeckmannClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = closure->alpha_y; + bsdf->T = closure->T; + + sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); +} + +ccl_device void osl_closure_microfacet_beckmann_refraction_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetBeckmannRefractionClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_TRANSMIT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->ior = closure->ior; + + sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf); +} + +/* Ashikhmin closures */ + +ccl_device void osl_closure_ashikhmin_velvet_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const AshikhminVelvetClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) { + return; + } + + ccl_private VelvetBsdf *bsdf = (ccl_private VelvetBsdf *)bsdf_alloc( + sd, sizeof(VelvetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->sigma = closure->sigma; + + sd->flag |= bsdf_ashikhmin_velvet_setup(bsdf); +} + +ccl_device void osl_closure_ashikhmin_shirley_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const AshikhminShirleyClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = closure->alpha_y; + bsdf->T = closure->T; + + sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf); +} + +ccl_device void osl_closure_diffuse_toon_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const DiffuseToonClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) { + return; + } + + ccl_private ToonBsdf *bsdf = (ccl_private ToonBsdf *)bsdf_alloc( + sd, sizeof(ToonBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->size = closure->size; + bsdf->smooth = closure->smooth; + + sd->flag |= bsdf_diffuse_toon_setup(bsdf); +} + +ccl_device void osl_closure_glossy_toon_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const GlossyToonClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY)) { + return; + } + + ccl_private ToonBsdf *bsdf = (ccl_private ToonBsdf *)bsdf_alloc( + sd, sizeof(ToonBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->size = closure->size; + bsdf->smooth = closure->smooth; + + sd->flag |= bsdf_glossy_toon_setup(bsdf); +} + +/* Disney principled closures */ + +ccl_device void osl_closure_principled_diffuse_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const PrincipledDiffuseClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) { + return; + } + + ccl_private PrincipledDiffuseBsdf *bsdf = (ccl_private PrincipledDiffuseBsdf *)bsdf_alloc( + sd, sizeof(PrincipledDiffuseBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->roughness = closure->roughness; + + sd->flag |= bsdf_principled_diffuse_setup(bsdf); +} + +ccl_device void osl_closure_principled_sheen_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const PrincipledSheenClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) { + return; + } + + ccl_private PrincipledSheenBsdf *bsdf = (ccl_private PrincipledSheenBsdf *)bsdf_alloc( + sd, sizeof(PrincipledSheenBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->avg_value = 0.0f; + + sd->flag |= bsdf_principled_sheen_setup(sd, bsdf); +} + +ccl_device void osl_closure_principled_clearcoat_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const PrincipledClearcoatClosure *closure) +{ + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->clearcoat_roughness; + bsdf->alpha_y = closure->clearcoat_roughness; + bsdf->ior = 1.5f; + + bsdf->extra = extra; + bsdf->extra->color = zero_spectrum(); + bsdf->extra->cspec0 = make_spectrum(0.04f); + bsdf->extra->clearcoat = closure->clearcoat; + + bsdf->T = zero_float3(); + + sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd); +} + +/* Variable cone emissive closure + * + * This primitive emits in a cone having a configurable penumbra area where the light decays to 0 + * reaching the outer_angle limit. It can also behave as a lambertian emitter if the provided + * angles are PI/2, which is the default + */ +ccl_device void osl_closure_emission_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t /* path_flag */, + float3 weight, + ccl_private const GenericEmissiveClosure *closure) +{ + emission_setup(sd, rgb_to_spectrum(weight)); +} + +/* Generic background closure + * + * We only have a background closure for the shaders to return a color in background shaders. No + * methods, only the weight is taking into account + */ +ccl_device void osl_closure_background_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t /* path_flag */, + float3 weight, + ccl_private const GenericBackgroundClosure *closure) +{ + background_setup(sd, rgb_to_spectrum(weight)); +} + +/* Holdout closure + * + * This will be used by the shader to mark the amount of holdout for the current shading point. No + * parameters, only the weight will be used + */ +ccl_device void osl_closure_holdout_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t /* path_flag */, + float3 weight, + ccl_private const HoldoutClosure *closure) +{ + closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, rgb_to_spectrum(weight)); + sd->flag |= SD_HOLDOUT; +} + +ccl_device void osl_closure_diffuse_ramp_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t /* path_flag */, + float3 weight, + ccl_private const DiffuseRampClosure *closure) +{ + ccl_private DiffuseRampBsdf *bsdf = (ccl_private DiffuseRampBsdf *)bsdf_alloc( + sd, sizeof(DiffuseRampBsdf), rgb_to_spectrum(weight)); + + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + + bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8); + if (!bsdf->colors) { + return; + } + + for (int i = 0; i < 8; i++) + bsdf->colors[i] = closure->colors[i]; + + sd->flag |= bsdf_diffuse_ramp_setup(bsdf); +} + +ccl_device void osl_closure_phong_ramp_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t /* path_flag */, + float3 weight, + ccl_private const PhongRampClosure *closure) +{ + ccl_private PhongRampBsdf *bsdf = (ccl_private PhongRampBsdf *)bsdf_alloc( + sd, sizeof(PhongRampBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->exponent = closure->exponent; + + bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8); + if (!bsdf->colors) { + return; + } + + for (int i = 0; i < 8; i++) + bsdf->colors[i] = closure->colors[i]; + + sd->flag |= bsdf_phong_ramp_setup(bsdf); +} + +ccl_device void osl_closure_bssrdf_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const BSSRDFClosure *closure) +{ + static ustring u_burley("burley"); + static ustring u_random_walk_fixed_radius("random_walk_fixed_radius"); + static ustring u_random_walk("random_walk"); + + ClosureType type; + if (closure->method == u_burley) { + type = CLOSURE_BSSRDF_BURLEY_ID; + } + else if (closure->method == u_random_walk_fixed_radius) { + type = CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID; + } + else if (closure->method == u_random_walk) { + type = CLOSURE_BSSRDF_RANDOM_WALK_ID; + } + else { + return; + } + + ccl_private Bssrdf *bssrdf = bssrdf_alloc(sd, rgb_to_spectrum(weight)); + if (!bssrdf) { + return; + } + + /* disable in case of diffuse ancestor, can't see it well then and + * adds considerably noise due to probabilities of continuing path + * getting lower and lower */ + if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR) { + bssrdf->radius = zero_spectrum(); + } + else { + bssrdf->radius = closure->radius; + } + + /* create one closure per color channel */ + bssrdf->albedo = closure->albedo; + bssrdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bssrdf->roughness = closure->roughness; + bssrdf->anisotropy = clamp(closure->anisotropy, 0.0f, 0.9f); + + sd->flag |= bssrdf_setup(sd, bssrdf, type, clamp(closure->ior, 1.01f, 3.8f)); +} + +/* Hair */ + +ccl_device void osl_closure_hair_reflection_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const HairReflectionClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY)) { + return; + } + + ccl_private HairBsdf *bsdf = (ccl_private HairBsdf *)bsdf_alloc( + sd, sizeof(HairBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->T = closure->T; + bsdf->roughness1 = closure->roughness1; + bsdf->roughness2 = closure->roughness2; + bsdf->offset = closure->offset; + + sd->flag |= bsdf_hair_reflection_setup(bsdf); +} + +ccl_device void osl_closure_hair_transmission_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const HairTransmissionClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY)) { + return; + } + + ccl_private HairBsdf *bsdf = (ccl_private HairBsdf *)bsdf_alloc( + sd, sizeof(HairBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->T = closure->T; + bsdf->roughness1 = closure->roughness1; + bsdf->roughness2 = closure->roughness2; + bsdf->offset = closure->offset; + + sd->flag |= bsdf_hair_transmission_setup(bsdf); +} + +ccl_device void osl_closure_principled_hair_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const PrincipledHairClosure *closure) +{ +#ifdef __HAIR__ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY)) { + return; + } + + ccl_private PrincipledHairBSDF *bsdf = (ccl_private PrincipledHairBSDF *)bsdf_alloc( + sd, sizeof(PrincipledHairBSDF), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + ccl_private PrincipledHairExtra *extra = (ccl_private PrincipledHairExtra *)closure_alloc_extra( + sd, sizeof(PrincipledHairExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->sigma = closure->sigma; + bsdf->v = closure->v; + bsdf->s = closure->s; + bsdf->alpha = closure->alpha; + bsdf->eta = closure->eta; + bsdf->m0_roughness = closure->m0_roughness; + + bsdf->extra = extra; + + sd->flag |= bsdf_principled_hair_setup(sd, bsdf); +#endif +} + +/* Volume */ + +ccl_device void osl_closure_absorption_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const VolumeAbsorptionClosure *closure) +{ + volume_extinction_setup(sd, rgb_to_spectrum(weight)); +} + +ccl_device void osl_closure_henyey_greenstein_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const VolumeHenyeyGreensteinClosure *closure) +{ + volume_extinction_setup(sd, rgb_to_spectrum(weight)); + + ccl_private HenyeyGreensteinVolume *volume = (ccl_private HenyeyGreensteinVolume *)bsdf_alloc( + sd, sizeof(HenyeyGreensteinVolume), rgb_to_spectrum(weight)); + if (!volume) { + return; + } + + volume->g = closure->g; + + sd->flag |= volume_henyey_greenstein_setup(volume); +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/closures_template.h b/intern/cycles/kernel/osl/closures_template.h new file mode 100644 index 00000000000..c808b275966 --- /dev/null +++ b/intern/cycles/kernel/osl/closures_template.h @@ -0,0 +1,258 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#ifndef OSL_CLOSURE_STRUCT_BEGIN +# define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) +#endif +#ifndef OSL_CLOSURE_STRUCT_END +# define OSL_CLOSURE_STRUCT_END(Upper, lower) +#endif +#ifndef OSL_CLOSURE_STRUCT_MEMBER +# define OSL_CLOSURE_STRUCT_MEMBER(Upper, TYPE, type, name, key) +#endif +#ifndef OSL_CLOSURE_STRUCT_ARRAY_MEMBER +# define OSL_CLOSURE_STRUCT_ARRAY_MEMBER(Upper, TYPE, type, name, key, size) +#endif + +OSL_CLOSURE_STRUCT_BEGIN(Diffuse, diffuse) + OSL_CLOSURE_STRUCT_MEMBER(Diffuse, VECTOR, packed_float3, N, NULL) +OSL_CLOSURE_STRUCT_END(Diffuse, diffuse) + +OSL_CLOSURE_STRUCT_BEGIN(OrenNayar, oren_nayar) + OSL_CLOSURE_STRUCT_MEMBER(OrenNayar, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(OrenNayar, FLOAT, float, roughness, NULL) +OSL_CLOSURE_STRUCT_END(OrenNayar, oren_nayar) + +OSL_CLOSURE_STRUCT_BEGIN(Translucent, translucent) + OSL_CLOSURE_STRUCT_MEMBER(Translucent, VECTOR, packed_float3, N, NULL) +OSL_CLOSURE_STRUCT_END(Translucent, translucent) + +OSL_CLOSURE_STRUCT_BEGIN(Reflection, reflection) + OSL_CLOSURE_STRUCT_MEMBER(Reflection, VECTOR, packed_float3, N, NULL) +OSL_CLOSURE_STRUCT_END(Reflection, reflection) + +OSL_CLOSURE_STRUCT_BEGIN(Refraction, refraction) + OSL_CLOSURE_STRUCT_MEMBER(Refraction, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(Refraction, FLOAT, float, ior, NULL) +OSL_CLOSURE_STRUCT_END(Refraction, refraction) + +OSL_CLOSURE_STRUCT_BEGIN(Transparent, transparent) +OSL_CLOSURE_STRUCT_END(Transparent, transparent) + +OSL_CLOSURE_STRUCT_BEGIN(Microfacet, microfacet) + OSL_CLOSURE_STRUCT_MEMBER(Microfacet, STRING, ustring, distribution, NULL) + OSL_CLOSURE_STRUCT_MEMBER(Microfacet, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(Microfacet, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(Microfacet, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(Microfacet, FLOAT, float, alpha_y, NULL) + OSL_CLOSURE_STRUCT_MEMBER(Microfacet, FLOAT, float, ior, NULL) + OSL_CLOSURE_STRUCT_MEMBER(Microfacet, INT, int, refract, NULL) +OSL_CLOSURE_STRUCT_END(Microfacet, microfacet) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXIsotropic, microfacet_ggx) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXIsotropic, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXIsotropic, FLOAT, float, alpha_x, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetGGXIsotropic, microfacet_ggx) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGX, microfacet_ggx_aniso) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, FLOAT, float, alpha_y, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetGGX, microfacet_ggx_aniso) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXRefraction, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXRefraction, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXRefraction, FLOAT, float, ior, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetGGXRefraction, microfacet_ggx_refraction) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGX, microfacet_multi_ggx) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, VECTOR, packed_float3, color, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGX, microfacet_multi_ggx) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXGlass, microfacet_multi_ggx_glass) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, FLOAT, float, ior, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, VECTOR, packed_float3, color, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXGlass, microfacet_multi_ggx_glass) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXAniso, microfacet_multi_ggx_aniso) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, FLOAT, float, alpha_y, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, VECTOR, packed_float3, color, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXAniso, microfacet_multi_ggx_aniso) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXFresnel, microfacet_ggx_fresnel) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, FLOAT, float, ior, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, VECTOR, packed_float3, color, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, VECTOR, packed_float3, cspec0, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetGGXFresnel, microfacet_ggx_fresnel) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXAnisoFresnel, microfacet_ggx_aniso_fresnel) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, FLOAT, float, alpha_y, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, FLOAT, float, ior, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, color, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, cspec0, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetGGXAnisoFresnel, microfacet_ggx_aniso_fresnel) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXFresnel, microfacet_multi_ggx_fresnel) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, FLOAT, float, ior, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, VECTOR, packed_float3, color, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, VECTOR, packed_float3, cspec0, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXFresnel, microfacet_multi_ggx_fresnel) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXGlassFresnel, microfacet_multi_ggx_glass_fresnel) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, FLOAT, float, ior, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, VECTOR, packed_float3, color, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, VECTOR, packed_float3, cspec0, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXGlassFresnel, microfacet_multi_ggx_glass_fresnel) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXAnisoFresnel, microfacet_multi_ggx_aniso_fresnel) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, FLOAT, float, alpha_y, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, FLOAT, float, ior, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, color, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, cspec0, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXAnisoFresnel, microfacet_multi_ggx_aniso_fresnel) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetBeckmannIsotropic, microfacet_beckmann) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannIsotropic, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannIsotropic, FLOAT, float, alpha_x, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetBeckmannIsotropic, microfacet_beckmann) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetBeckmann, microfacet_beckmann_aniso) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, FLOAT, float, alpha_y, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetBeckmann, microfacet_beckmann_aniso) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannRefraction, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannRefraction, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannRefraction, FLOAT, float, ior, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction) + +OSL_CLOSURE_STRUCT_BEGIN(AshikhminShirley, ashikhmin_shirley) + OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, FLOAT, float, alpha_y, NULL) +OSL_CLOSURE_STRUCT_END(AshikhminShirley, ashikhmin_shirley) + +OSL_CLOSURE_STRUCT_BEGIN(AshikhminVelvet, ashikhmin_velvet) + OSL_CLOSURE_STRUCT_MEMBER(AshikhminVelvet, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(AshikhminVelvet, FLOAT, float, sigma, NULL) +OSL_CLOSURE_STRUCT_END(AshikhminVelvet, ashikhmin_velvet) + +OSL_CLOSURE_STRUCT_BEGIN(DiffuseToon, diffuse_toon) + OSL_CLOSURE_STRUCT_MEMBER(DiffuseToon, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(DiffuseToon, FLOAT, float, size, NULL) + OSL_CLOSURE_STRUCT_MEMBER(DiffuseToon, FLOAT, float, smooth, NULL) +OSL_CLOSURE_STRUCT_END(DiffuseToon, diffuse_toon) + +OSL_CLOSURE_STRUCT_BEGIN(GlossyToon, glossy_toon) + OSL_CLOSURE_STRUCT_MEMBER(GlossyToon, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(GlossyToon, FLOAT, float, size, NULL) + OSL_CLOSURE_STRUCT_MEMBER(GlossyToon, FLOAT, float, smooth, NULL) +OSL_CLOSURE_STRUCT_END(GlossyToon, glossy_toon) + +OSL_CLOSURE_STRUCT_BEGIN(PrincipledDiffuse, principled_diffuse) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledDiffuse, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledDiffuse, FLOAT, float, roughness, NULL) +OSL_CLOSURE_STRUCT_END(PrincipledDiffuse, principled_diffuse) + +OSL_CLOSURE_STRUCT_BEGIN(PrincipledSheen, principled_sheen) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledSheen, VECTOR, packed_float3, N, NULL) +OSL_CLOSURE_STRUCT_END(PrincipledSheen, principled_sheen) + +OSL_CLOSURE_STRUCT_BEGIN(PrincipledClearcoat, principled_clearcoat) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledClearcoat, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledClearcoat, FLOAT, float, clearcoat, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledClearcoat, FLOAT, float, clearcoat_roughness, NULL) +OSL_CLOSURE_STRUCT_END(PrincipledClearcoat, principled_clearcoat) + +OSL_CLOSURE_STRUCT_BEGIN(GenericEmissive, emission) +OSL_CLOSURE_STRUCT_END(GenericEmissive, emission) + +OSL_CLOSURE_STRUCT_BEGIN(GenericBackground, background) +OSL_CLOSURE_STRUCT_END(GenericBackground, background) + +OSL_CLOSURE_STRUCT_BEGIN(Holdout, holdout) +OSL_CLOSURE_STRUCT_END(Holdout, holdout) + +OSL_CLOSURE_STRUCT_BEGIN(DiffuseRamp, diffuse_ramp) + OSL_CLOSURE_STRUCT_MEMBER(DiffuseRamp, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_ARRAY_MEMBER(DiffuseRamp, COLOR, packed_float3, colors, NULL, 8) +OSL_CLOSURE_STRUCT_END(DiffuseRamp, diffuse_ramp) + +OSL_CLOSURE_STRUCT_BEGIN(PhongRamp, phong_ramp) + OSL_CLOSURE_STRUCT_MEMBER(PhongRamp, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PhongRamp, FLOAT, float, exponent, NULL) + OSL_CLOSURE_STRUCT_ARRAY_MEMBER(PhongRamp, COLOR, packed_float3, colors, NULL, 8) +OSL_CLOSURE_STRUCT_END(PhongRamp, phong_ramp) + +OSL_CLOSURE_STRUCT_BEGIN(BSSRDF, bssrdf) + OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, STRING, ustring, method, NULL) + OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, VECTOR, packed_float3, radius, NULL) + OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, VECTOR, packed_float3, albedo, NULL) + OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, FLOAT, float, roughness, "roughness") + OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, FLOAT, float, ior, "ior") + OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, FLOAT, float, anisotropy, "anisotropy") +OSL_CLOSURE_STRUCT_END(BSSRDF, bssrdf) + +OSL_CLOSURE_STRUCT_BEGIN(HairReflection, hair_reflection) + OSL_CLOSURE_STRUCT_MEMBER(HairReflection, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(HairReflection, FLOAT, float, roughness1, NULL) + OSL_CLOSURE_STRUCT_MEMBER(HairReflection, FLOAT, float, roughness2, NULL) + OSL_CLOSURE_STRUCT_MEMBER(HairReflection, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(HairReflection, FLOAT, float, offset, NULL) +OSL_CLOSURE_STRUCT_END(HairReflection, hair_reflection) + +OSL_CLOSURE_STRUCT_BEGIN(HairTransmission, hair_transmission) + OSL_CLOSURE_STRUCT_MEMBER(HairTransmission, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(HairTransmission, FLOAT, float, roughness1, NULL) + OSL_CLOSURE_STRUCT_MEMBER(HairTransmission, FLOAT, float, roughness2, NULL) + OSL_CLOSURE_STRUCT_MEMBER(HairReflection, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(HairReflection, FLOAT, float, offset, NULL) +OSL_CLOSURE_STRUCT_END(HairTransmission, hair_transmission) + +OSL_CLOSURE_STRUCT_BEGIN(PrincipledHair, principled_hair) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, VECTOR, packed_float3, sigma, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, v, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, s, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, m0_roughness, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, alpha, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, eta, NULL) +OSL_CLOSURE_STRUCT_END(PrincipledHair, principled_hair) + +OSL_CLOSURE_STRUCT_BEGIN(VolumeAbsorption, absorption) +OSL_CLOSURE_STRUCT_END(VolumeAbsorption, absorption) + +OSL_CLOSURE_STRUCT_BEGIN(VolumeHenyeyGreenstein, henyey_greenstein) + OSL_CLOSURE_STRUCT_MEMBER(VolumeHenyeyGreenstein, FLOAT, float, g, NULL) +OSL_CLOSURE_STRUCT_END(VolumeHenyeyGreenstein, henyey_greenstein) + +#undef OSL_CLOSURE_STRUCT_BEGIN +#undef OSL_CLOSURE_STRUCT_END +#undef OSL_CLOSURE_STRUCT_MEMBER +#undef OSL_CLOSURE_STRUCT_ARRAY_MEMBER diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp deleted file mode 100644 index 8d1928d0126..00000000000 --- a/intern/cycles/kernel/osl/emissive.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Adapted from Open Shading Language - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011-2022 Blender Foundation. */ - -#include <OpenImageIO/fmath.h> - -#include <OSL/genclosure.h> - -#include "kernel/osl/closures.h" - -// clang-format off -#include "kernel/device/cpu/compat.h" -#include "kernel/device/cpu/globals.h" - -#include "kernel/types.h" -#include "kernel/closure/alloc.h" -#include "kernel/closure/emissive.h" - -#include "kernel/util/color.h" -// clang-format on - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -/// Variable cone emissive closure -/// -/// This primitive emits in a cone having a configurable -/// penumbra area where the light decays to 0 reaching the -/// outer_angle limit. It can also behave as a lambertian emitter -/// if the provided angles are PI/2, which is the default -/// -class GenericEmissiveClosure : public CClosurePrimitive { - public: - void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight) - { - emission_setup(sd, rgb_to_spectrum(weight)); - } -}; - -ClosureParam *closure_emission_params() -{ - static ClosureParam params[] = {CLOSURE_STRING_KEYPARAM(GenericEmissiveClosure, label, "label"), - CLOSURE_FINISH_PARAM(GenericEmissiveClosure)}; - return params; -} - -CCLOSURE_PREPARE(closure_emission_prepare, GenericEmissiveClosure) - -CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/services.cpp b/intern/cycles/kernel/osl/services.cpp index eef661c203e..334f06861b2 100644 --- a/intern/cycles/kernel/osl/services.cpp +++ b/intern/cycles/kernel/osl/services.cpp @@ -18,7 +18,6 @@ #include "scene/pointcloud.h" #include "scene/scene.h" -#include "kernel/osl/closures.h" #include "kernel/osl/globals.h" #include "kernel/osl/services.h" #include "kernel/osl/shader.h" @@ -1605,8 +1604,8 @@ bool OSLRenderServices::trace(TraceOpt &options, /* setup ray */ Ray ray; - ray.P = TO_FLOAT3(P); - ray.D = TO_FLOAT3(R); + ray.P = make_float3(P.x, P.y, P.z); + ray.D = make_float3(R.x, R.y, R.z); ray.tmin = 0.0f; ray.tmax = (options.maxdist == 1.0e30f) ? FLT_MAX : options.maxdist - options.mindist; ray.time = sd->time; @@ -1629,12 +1628,12 @@ bool OSLRenderServices::trace(TraceOpt &options, /* ray differentials */ differential3 dP; - dP.dx = TO_FLOAT3(dPdx); - dP.dy = TO_FLOAT3(dPdy); + dP.dx = make_float3(dPdx.x, dPdx.y, dPdx.z); + dP.dy = make_float3(dPdy.x, dPdy.y, dPdy.z); ray.dP = differential_make_compact(dP); differential3 dD; - dD.dx = TO_FLOAT3(dRdx); - dD.dy = TO_FLOAT3(dRdy); + dD.dx = make_float3(dRdx.x, dRdx.y, dRdx.z); + dD.dy = make_float3(dRdy.x, dRdy.y, dRdy.z); ray.dD = differential_make_compact(dD); /* allocate trace data */ diff --git a/intern/cycles/kernel/osl/services.h b/intern/cycles/kernel/osl/services.h index edffd912bad..eb4e35f80a2 100644 --- a/intern/cycles/kernel/osl/services.h +++ b/intern/cycles/kernel/osl/services.h @@ -76,6 +76,8 @@ class OSLRenderServices : public OSL::RendererServices { OSLRenderServices(OSL::TextureSystem *texture_system); ~OSLRenderServices(); + static void register_closures(OSL::ShadingSystem *ss); + bool get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, OSL::TransformationPtr xform, diff --git a/intern/cycles/kernel/osl/shader.cpp b/intern/cycles/kernel/osl/shader.cpp index 3355f5c869a..83fdfab1217 100644 --- a/intern/cycles/kernel/osl/shader.cpp +++ b/intern/cycles/kernel/osl/shader.cpp @@ -13,14 +13,19 @@ #include "kernel/integrator/state.h" -#include "kernel/osl/closures.h" #include "kernel/osl/globals.h" #include "kernel/osl/services.h" #include "kernel/osl/shader.h" +#include "kernel/osl/types.h" +#include "kernel/osl/closures_setup.h" + #include "kernel/util/differential.h" // clang-format on +#define TO_VEC3(v) OSL::Vec3(v.x, v.y, v.z) +#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2]) + CCL_NAMESPACE_BEGIN /* Threads */ @@ -133,7 +138,8 @@ static void shaderdata_to_shaderglobals(const KernelGlobalsCPU *kg, /* Surface */ -static void flatten_surface_closure_tree(ShaderData *sd, +static void flatten_surface_closure_tree(const KernelGlobalsCPU *kg, + ShaderData *sd, uint32_t path_flag, const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f)) @@ -144,27 +150,30 @@ static void flatten_surface_closure_tree(ShaderData *sd, switch (closure->id) { case OSL::ClosureColor::MUL: { OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; - flatten_surface_closure_tree(sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight); + flatten_surface_closure_tree(kg, sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight); break; } case OSL::ClosureColor::ADD: { OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; - flatten_surface_closure_tree(sd, path_flag, add->closureA, weight); - flatten_surface_closure_tree(sd, path_flag, add->closureB, weight); + flatten_surface_closure_tree(kg, sd, path_flag, add->closureA, weight); + flatten_surface_closure_tree(kg, sd, path_flag, add->closureB, weight); break; } - default: { - OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; - CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); - - if (prim) { -#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS - weight = weight * TO_FLOAT3(comp->w); -#endif - prim->setup(sd, path_flag, weight); - } +#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \ + case OSL_CLOSURE_##Upper##_ID: { \ + const OSL::ClosureComponent *comp = \ + reinterpret_cast<const OSL::ClosureComponent *>(closure); \ + weight *= TO_FLOAT3(comp->w); \ + osl_closure_##lower##_setup(kg, \ + sd, \ + path_flag, \ + weight, \ + reinterpret_cast<const Upper##Closure *>(comp + 1)); \ + break; \ + } +#include "closures_template.h" + default: break; - } } } @@ -238,12 +247,13 @@ void OSLShader::eval_surface(const KernelGlobalsCPU *kg, /* flatten closure tree */ if (globals->Ci) - flatten_surface_closure_tree(sd, path_flag, globals->Ci); + flatten_surface_closure_tree(kg, sd, path_flag, globals->Ci); } /* Background */ -static void flatten_background_closure_tree(ShaderData *sd, +static void flatten_background_closure_tree(const KernelGlobalsCPU *kg, + ShaderData *sd, const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f)) { @@ -254,28 +264,27 @@ static void flatten_background_closure_tree(ShaderData *sd, switch (closure->id) { case OSL::ClosureColor::MUL: { OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; - flatten_background_closure_tree(sd, mul->closure, weight * TO_FLOAT3(mul->weight)); + flatten_background_closure_tree(kg, sd, mul->closure, weight * TO_FLOAT3(mul->weight)); break; } case OSL::ClosureColor::ADD: { OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; - flatten_background_closure_tree(sd, add->closureA, weight); - flatten_background_closure_tree(sd, add->closureB, weight); + flatten_background_closure_tree(kg, sd, add->closureA, weight); + flatten_background_closure_tree(kg, sd, add->closureB, weight); break; } - default: { - OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; - CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); - - if (prim) { -#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS - weight = weight * TO_FLOAT3(comp->w); -#endif - prim->setup(sd, 0, weight); - } +#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \ + case OSL_CLOSURE_##Upper##_ID: { \ + const OSL::ClosureComponent *comp = reinterpret_cast<const OSL::ClosureComponent *>(closure); \ + weight *= TO_FLOAT3(comp->w); \ + osl_closure_##lower##_setup( \ + kg, sd, 0, weight, reinterpret_cast<const Upper##Closure *>(comp + 1)); \ + break; \ + } +#include "closures_template.h" + default: break; - } } } @@ -299,12 +308,13 @@ void OSLShader::eval_background(const KernelGlobalsCPU *kg, /* return background color immediately */ if (globals->Ci) - flatten_background_closure_tree(sd, globals->Ci); + flatten_background_closure_tree(kg, sd, globals->Ci); } /* Volume */ -static void flatten_volume_closure_tree(ShaderData *sd, +static void flatten_volume_closure_tree(const KernelGlobalsCPU *kg, + ShaderData *sd, const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f)) { @@ -314,26 +324,26 @@ static void flatten_volume_closure_tree(ShaderData *sd, switch (closure->id) { case OSL::ClosureColor::MUL: { OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; - flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight); + flatten_volume_closure_tree(kg, sd, mul->closure, TO_FLOAT3(mul->weight) * weight); break; } case OSL::ClosureColor::ADD: { OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; - flatten_volume_closure_tree(sd, add->closureA, weight); - flatten_volume_closure_tree(sd, add->closureB, weight); + flatten_volume_closure_tree(kg, sd, add->closureA, weight); + flatten_volume_closure_tree(kg, sd, add->closureB, weight); break; } - default: { - OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; - CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); - - if (prim) { -#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS - weight = weight * TO_FLOAT3(comp->w); -#endif - prim->setup(sd, 0, weight); - } - } +#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \ + case OSL_CLOSURE_##Upper##_ID: { \ + const OSL::ClosureComponent *comp = reinterpret_cast<const OSL::ClosureComponent *>(closure); \ + weight *= TO_FLOAT3(comp->w); \ + osl_closure_##lower##_setup( \ + kg, sd, 0, weight, reinterpret_cast<const Upper##Closure *>(comp + 1)); \ + break; \ + } +#include "closures_template.h" + default: + break; } } @@ -358,7 +368,7 @@ void OSLShader::eval_volume(const KernelGlobalsCPU *kg, /* flatten closure tree */ if (globals->Ci) - flatten_volume_closure_tree(sd, globals->Ci); + flatten_volume_closure_tree(kg, sd, globals->Ci); } /* Displacement */ diff --git a/intern/cycles/kernel/osl/shader.h b/intern/cycles/kernel/osl/shader.h index 56c87d7c8ac..c89eecb7698 100644 --- a/intern/cycles/kernel/osl/shader.h +++ b/intern/cycles/kernel/osl/shader.h @@ -33,9 +33,6 @@ struct OSLShadingSystem; class OSLShader { public: - /* init */ - static void register_closures(OSLShadingSystem *ss); - /* per thread data */ static void thread_init(KernelGlobalsCPU *kg, OSLGlobals *osl_globals); static void thread_free(KernelGlobalsCPU *kg); diff --git a/intern/cycles/kernel/osl/types.h b/intern/cycles/kernel/osl/types.h new file mode 100644 index 00000000000..14feb16aad4 --- /dev/null +++ b/intern/cycles/kernel/osl/types.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#pragma once + +CCL_NAMESPACE_BEGIN + +/* Closure */ + +enum ClosureTypeOSL { + OSL_CLOSURE_MUL_ID = -1, + OSL_CLOSURE_ADD_ID = -2, + + OSL_CLOSURE_NONE_ID = 0, + +#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) OSL_CLOSURE_##Upper##_ID, +#include "closures_template.h" +}; + + +CCL_NAMESPACE_END diff --git a/intern/cycles/scene/osl.cpp b/intern/cycles/scene/osl.cpp index 7c8d9bcd3e2..f0246b5b40e 100644 --- a/intern/cycles/scene/osl.cpp +++ b/intern/cycles/scene/osl.cpp @@ -298,7 +298,7 @@ void OSLShaderManager::shading_system_init() const int nraytypes = sizeof(raytypes) / sizeof(raytypes[0]); ss_shared->attribute("raytypes", TypeDesc(TypeDesc::STRING, nraytypes), raytypes); - OSLShader::register_closures((OSLShadingSystem *)ss_shared); + OSLRenderServices::register_closures(ss_shared); loaded_shaders.clear(); } |