Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorPatrick Mours <pmours@nvidia.com>2022-09-08 20:31:44 +0300
committerPatrick Mours <pmours@nvidia.com>2022-09-09 16:47:37 +0300
commit8611c37f975737efe0d159822edfc21733268f51 (patch)
treee7d7ce6b36fe7008c26b9fee5d90f906fe4faf5c /intern
parentef7c9e793ec5331ac694eec9336565bd2254c406 (diff)
Cycles: Generate OSL closures using macros and a template file
This has the advantage of being able to use information about the existing OSL closures in various places without code duplication. In addition, the setup code for all closures was moved to standalone functions to avoid usage of virtual function calls in preparation for GPU support. This patch was split from D15902. Differential Revision: https://developer.blender.org/D15917
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/kernel/closure/alloc.h30
-rw-r--r--intern/cycles/kernel/osl/CMakeLists.txt8
-rw-r--r--intern/cycles/kernel/osl/background.cpp77
-rw-r--r--intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp68
-rw-r--r--intern/cycles/kernel/osl/bsdf_phong_ramp.cpp69
-rw-r--r--intern/cycles/kernel/osl/bssrdf.cpp105
-rw-r--r--intern/cycles/kernel/osl/closures.cpp1001
-rw-r--r--intern/cycles/kernel/osl/closures.h142
-rw-r--r--intern/cycles/kernel/osl/closures_setup.h1166
-rw-r--r--intern/cycles/kernel/osl/closures_template.h258
-rw-r--r--intern/cycles/kernel/osl/emissive.cpp54
-rw-r--r--intern/cycles/kernel/osl/services.cpp13
-rw-r--r--intern/cycles/kernel/osl/services.h2
-rw-r--r--intern/cycles/kernel/osl/shader.cpp108
-rw-r--r--intern/cycles/kernel/osl/shader.h3
-rw-r--r--intern/cycles/kernel/osl/types.h21
-rw-r--r--intern/cycles/scene/osl.cpp2
17 files changed, 1540 insertions, 1587 deletions
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), &params);
-
- 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), &params);
-
- 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), &params);
- 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), &params);
- 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), &params);
- 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), &params);
-
- 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), &params);
- 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), &params);
- 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), &params);
- 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), &params);
- 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), &params); \
- 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();
}