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
diff options
context:
space:
mode:
authorJeroen Bakker <j.bakker@atmind.nl>2022-09-09 22:09:51 +0300
committerJeroen Bakker <j.bakker@atmind.nl>2022-09-09 22:09:51 +0300
commit5082fd5e63737bf8cb76478d143647e1907d13f4 (patch)
tree8736fcf031cdee3a7c10d0a7ebc60578f81dea06 /intern/cycles
parentb3400d012a33fa774a20893993b3e7ed9b9f1f97 (diff)
parent1e1e9014cfc9f47d8496dd283a1cccae0ce29552 (diff)
Merge branch 'master' into temp-T73411-add-scene-parameters
Diffstat (limited to 'intern/cycles')
-rw-r--r--intern/cycles/blender/session.cpp2
-rw-r--r--intern/cycles/blender/session.h2
-rw-r--r--intern/cycles/kernel/closure/alloc.h30
-rw-r--r--intern/cycles/kernel/geom/attribute.h32
-rw-r--r--intern/cycles/kernel/geom/primitive.h10
-rw-r--r--intern/cycles/kernel/geom/subd_triangle.h8
-rw-r--r--intern/cycles/kernel/geom/volume.h2
-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/globals.h8
-rw-r--r--intern/cycles/kernel/osl/services.cpp173
-rw-r--r--intern/cycles/kernel/osl/services.h2
-rw-r--r--intern/cycles/kernel/osl/shader.cpp144
-rw-r--r--intern/cycles/kernel/osl/shader.h9
-rw-r--r--intern/cycles/kernel/osl/types.h21
-rw-r--r--intern/cycles/kernel/types.h11
-rw-r--r--intern/cycles/scene/geometry.cpp152
-rw-r--r--intern/cycles/scene/geometry.h4
-rw-r--r--intern/cycles/scene/osl.cpp14
-rw-r--r--intern/cycles/scene/osl.h3
-rw-r--r--intern/cycles/scene/shader.cpp8
-rw-r--r--intern/cycles/scene/shader.h6
30 files changed, 1697 insertions, 1892 deletions
diff --git a/intern/cycles/blender/session.cpp b/intern/cycles/blender/session.cpp
index 321771b67a5..1b7aa38efb4 100644
--- a/intern/cycles/blender/session.cpp
+++ b/intern/cycles/blender/session.cpp
@@ -704,7 +704,7 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
buffer_params.window_width = bake_width;
buffer_params.window_height = bake_height;
/* Unique layer name for multi-image baking. */
- buffer_params.layer = string_printf("bake_%d\n", (int)full_buffer_files_.size());
+ buffer_params.layer = string_printf("bake_%d\n", bake_id++);
/* Update session. */
session->reset(session_params, buffer_params);
diff --git a/intern/cycles/blender/session.h b/intern/cycles/blender/session.h
index f9a5b6faf7e..ceca86016b8 100644
--- a/intern/cycles/blender/session.h
+++ b/intern/cycles/blender/session.h
@@ -146,6 +146,8 @@ class BlenderSession {
BlenderDisplayDriver *display_driver_ = nullptr;
vector<string> full_buffer_files_;
+
+ int bake_id = 0;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/closure/alloc.h b/intern/cycles/kernel/closure/alloc.h
index 9847898ee89..1cf06614f3b 100644
--- a/intern/cycles/kernel/closure/alloc.h
+++ b/intern/cycles/kernel/closure/alloc.h
@@ -59,39 +59,10 @@ ccl_device_inline ccl_private ShaderClosure *bsdf_alloc(ccl_private ShaderData *
* we will not allocate new closure. */
if (sample_weight >= CLOSURE_WEIGHT_CUTOFF) {
ccl_private ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight);
- if (sc == NULL) {
- return NULL;
- }
-
- sc->sample_weight = sample_weight;
-
- return sc;
- }
-
- return NULL;
-}
-
-#ifdef __OSL__
-ccl_device_inline ShaderClosure *bsdf_alloc_osl(ShaderData *sd,
- int size,
- Spectrum weight,
- void *data)
-{
- kernel_assert(isfinite_safe(weight));
-
- const float sample_weight = fabsf(average(weight));
-
- /* Use comparison this way to help dealing with non-finite weight: if the average is not finite
- * we will not allocate new closure. */
- if (sample_weight >= CLOSURE_WEIGHT_CUTOFF) {
- ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight);
if (!sc) {
return NULL;
}
- memcpy((void *)sc, data, size);
-
- sc->weight = weight;
sc->sample_weight = sample_weight;
return sc;
@@ -99,6 +70,5 @@ ccl_device_inline ShaderClosure *bsdf_alloc_osl(ShaderData *sd,
return NULL;
}
-#endif
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/geom/attribute.h b/intern/cycles/kernel/geom/attribute.h
index 31a9e39d528..3a0ee1b09d1 100644
--- a/intern/cycles/kernel/geom/attribute.h
+++ b/intern/cycles/kernel/geom/attribute.h
@@ -16,14 +16,14 @@ CCL_NAMESPACE_BEGIN
/* Patch index for triangle, -1 if not subdivision triangle */
-ccl_device_inline uint subd_triangle_patch(KernelGlobals kg, ccl_private const ShaderData *sd)
+ccl_device_inline uint subd_triangle_patch(KernelGlobals kg, int prim)
{
- return (sd->prim != PRIM_NONE) ? kernel_data_fetch(tri_patch, sd->prim) : ~0;
+ return (prim != PRIM_NONE) ? kernel_data_fetch(tri_patch, prim) : ~0;
}
-ccl_device_inline uint attribute_primitive_type(KernelGlobals kg, ccl_private const ShaderData *sd)
+ccl_device_inline uint attribute_primitive_type(KernelGlobals kg, int prim, int type)
{
- if ((sd->type & PRIMITIVE_TRIANGLE) && subd_triangle_patch(kg, sd) != ~0) {
+ if ((type & PRIMITIVE_TRIANGLE) && subd_triangle_patch(kg, prim) != ~0) {
return ATTR_PRIM_SUBD;
}
else {
@@ -45,17 +45,16 @@ ccl_device_inline uint object_attribute_map_offset(KernelGlobals kg, int object)
return kernel_data_fetch(objects, object).attribute_map_offset;
}
-ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg,
- ccl_private const ShaderData *sd,
- uint id)
+ccl_device_inline AttributeDescriptor
+find_attribute(KernelGlobals kg, int object, int prim, int type, uint64_t id)
{
- if (sd->object == OBJECT_NONE) {
+ if (object == OBJECT_NONE) {
return attribute_not_found();
}
/* for SVM, find attribute by unique id */
- uint attr_offset = object_attribute_map_offset(kg, sd->object);
- attr_offset += attribute_primitive_type(kg, sd);
+ uint attr_offset = object_attribute_map_offset(kg, object);
+ attr_offset += attribute_primitive_type(kg, prim, type);
AttributeMap attr_map = kernel_data_fetch(attributes_map, attr_offset);
while (attr_map.id != id) {
@@ -77,7 +76,7 @@ ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg,
AttributeDescriptor desc;
desc.element = (AttributeElement)attr_map.element;
- if (sd->prim == PRIM_NONE && desc.element != ATTR_ELEMENT_MESH &&
+ if (prim == PRIM_NONE && desc.element != ATTR_ELEMENT_MESH &&
desc.element != ATTR_ELEMENT_VOXEL && desc.element != ATTR_ELEMENT_OBJECT) {
return attribute_not_found();
}
@@ -91,11 +90,16 @@ ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg,
return desc;
}
+ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg,
+ ccl_private const ShaderData *sd,
+ uint64_t id)
+{
+ return find_attribute(kg, sd->object, sd->prim, sd->type, id);
+}
+
/* Transform matrix attribute on meshes */
-ccl_device Transform primitive_attribute_matrix(KernelGlobals kg,
- ccl_private const ShaderData *sd,
- const AttributeDescriptor desc)
+ccl_device Transform primitive_attribute_matrix(KernelGlobals kg, const AttributeDescriptor desc)
{
Transform tfm;
diff --git a/intern/cycles/kernel/geom/primitive.h b/intern/cycles/kernel/geom/primitive.h
index 0f1a3fc11bc..04b04ff5985 100644
--- a/intern/cycles/kernel/geom/primitive.h
+++ b/intern/cycles/kernel/geom/primitive.h
@@ -25,7 +25,7 @@ ccl_device_forceinline float primitive_surface_attribute_float(KernelGlobals kg,
ccl_private float *dy)
{
if (sd->type & PRIMITIVE_TRIANGLE) {
- if (subd_triangle_patch(kg, sd) == ~0)
+ if (subd_triangle_patch(kg, sd->prim) == ~0)
return triangle_attribute_float(kg, sd, desc, dx, dy);
else
return subd_triangle_attribute_float(kg, sd, desc, dx, dy);
@@ -56,7 +56,7 @@ ccl_device_forceinline float2 primitive_surface_attribute_float2(KernelGlobals k
ccl_private float2 *dy)
{
if (sd->type & PRIMITIVE_TRIANGLE) {
- if (subd_triangle_patch(kg, sd) == ~0)
+ if (subd_triangle_patch(kg, sd->prim) == ~0)
return triangle_attribute_float2(kg, sd, desc, dx, dy);
else
return subd_triangle_attribute_float2(kg, sd, desc, dx, dy);
@@ -87,7 +87,7 @@ ccl_device_forceinline float3 primitive_surface_attribute_float3(KernelGlobals k
ccl_private float3 *dy)
{
if (sd->type & PRIMITIVE_TRIANGLE) {
- if (subd_triangle_patch(kg, sd) == ~0)
+ if (subd_triangle_patch(kg, sd->prim) == ~0)
return triangle_attribute_float3(kg, sd, desc, dx, dy);
else
return subd_triangle_attribute_float3(kg, sd, desc, dx, dy);
@@ -118,7 +118,7 @@ ccl_device_forceinline float4 primitive_surface_attribute_float4(KernelGlobals k
ccl_private float4 *dy)
{
if (sd->type & PRIMITIVE_TRIANGLE) {
- if (subd_triangle_patch(kg, sd) == ~0)
+ if (subd_triangle_patch(kg, sd->prim) == ~0)
return triangle_attribute_float4(kg, sd, desc, dx, dy);
else
return subd_triangle_attribute_float4(kg, sd, desc, dx, dy);
@@ -320,7 +320,7 @@ ccl_device_forceinline float4 primitive_motion_vector(KernelGlobals kg,
#endif
if (sd->type & PRIMITIVE_TRIANGLE) {
/* Triangle */
- if (subd_triangle_patch(kg, sd) == ~0) {
+ if (subd_triangle_patch(kg, sd->prim) == ~0) {
motion_pre = triangle_attribute_float3(kg, sd, desc, NULL, NULL);
desc.offset += numverts;
motion_post = triangle_attribute_float3(kg, sd, desc, NULL, NULL);
diff --git a/intern/cycles/kernel/geom/subd_triangle.h b/intern/cycles/kernel/geom/subd_triangle.h
index c6f883461bd..784ba377318 100644
--- a/intern/cycles/kernel/geom/subd_triangle.h
+++ b/intern/cycles/kernel/geom/subd_triangle.h
@@ -87,7 +87,7 @@ ccl_device_noinline float subd_triangle_attribute_float(KernelGlobals kg,
ccl_private float *dx,
ccl_private float *dy)
{
- int patch = subd_triangle_patch(kg, sd);
+ int patch = subd_triangle_patch(kg, sd->prim);
#ifdef __PATCH_EVAL__
if (desc.flags & ATTR_SUBDIVIDED) {
@@ -226,7 +226,7 @@ ccl_device_noinline float2 subd_triangle_attribute_float2(KernelGlobals kg,
ccl_private float2 *dx,
ccl_private float2 *dy)
{
- int patch = subd_triangle_patch(kg, sd);
+ int patch = subd_triangle_patch(kg, sd->prim);
#ifdef __PATCH_EVAL__
if (desc.flags & ATTR_SUBDIVIDED) {
@@ -368,7 +368,7 @@ ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals kg,
ccl_private float3 *dx,
ccl_private float3 *dy)
{
- int patch = subd_triangle_patch(kg, sd);
+ int patch = subd_triangle_patch(kg, sd->prim);
#ifdef __PATCH_EVAL__
if (desc.flags & ATTR_SUBDIVIDED) {
@@ -509,7 +509,7 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals kg,
ccl_private float4 *dx,
ccl_private float4 *dy)
{
- int patch = subd_triangle_patch(kg, sd);
+ int patch = subd_triangle_patch(kg, sd->prim);
#ifdef __PATCH_EVAL__
if (desc.flags & ATTR_SUBDIVIDED) {
diff --git a/intern/cycles/kernel/geom/volume.h b/intern/cycles/kernel/geom/volume.h
index 3510a905def..885a420c97f 100644
--- a/intern/cycles/kernel/geom/volume.h
+++ b/intern/cycles/kernel/geom/volume.h
@@ -29,7 +29,7 @@ ccl_device_inline float3 volume_normalized_position(KernelGlobals kg,
object_inverse_position_transform(kg, sd, &P);
if (desc.offset != ATTR_STD_NOT_FOUND) {
- Transform tfm = primitive_attribute_matrix(kg, sd, desc);
+ Transform tfm = primitive_attribute_matrix(kg, desc);
P = transform_point(&tfm, P);
}
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/globals.h b/intern/cycles/kernel/osl/globals.h
index 172091c55f5..496965a50ec 100644
--- a/intern/cycles/kernel/osl/globals.h
+++ b/intern/cycles/kernel/osl/globals.h
@@ -56,16 +56,8 @@ struct OSLGlobals {
OSL::ShaderGroupRef background_state;
/* attributes */
- struct Attribute {
- TypeDesc type;
- AttributeDescriptor desc;
- ParamValue value;
- };
-
- typedef unordered_map<ustring, Attribute, ustringHash> AttributeMap;
typedef unordered_map<ustring, int, ustringHash> ObjectNameMap;
- vector<AttributeMap> attribute_map;
ObjectNameMap object_name_map;
vector<ustring> object_names;
};
diff --git a/intern/cycles/kernel/osl/services.cpp b/intern/cycles/kernel/osl/services.cpp
index faa027f4e1e..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"
@@ -740,76 +739,75 @@ static bool set_attribute_matrix(const Transform &tfm, TypeDesc type, void *val)
return false;
}
-static bool get_primitive_attribute(const KernelGlobalsCPU *kg,
- const ShaderData *sd,
- const OSLGlobals::Attribute &attr,
- const TypeDesc &type,
- bool derivatives,
- void *val)
+static bool get_object_attribute(const KernelGlobalsCPU *kg,
+ ShaderData *sd,
+ const AttributeDescriptor &desc,
+ const TypeDesc &type,
+ bool derivatives,
+ void *val)
{
- if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
- attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) {
+ if (desc.type == NODE_ATTR_FLOAT3) {
float3 fval[3];
- if (primitive_is_volume_attribute(sd, attr.desc)) {
- fval[0] = primitive_volume_attribute_float3(kg, sd, attr.desc);
+#ifdef __VOLUME__
+ if (primitive_is_volume_attribute(sd, desc)) {
+ fval[0] = primitive_volume_attribute_float3(kg, sd, desc);
}
- else {
+ else
+#endif
+ {
memset(fval, 0, sizeof(fval));
fval[0] = primitive_surface_attribute_float3(
- kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ kg, sd, desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
}
return set_attribute_float3(fval, type, derivatives, val);
}
- else if (attr.type == TypeFloat2) {
- if (primitive_is_volume_attribute(sd, attr.desc)) {
+ else if (desc.type == NODE_ATTR_FLOAT2) {
+#ifdef __VOLUME__
+ if (primitive_is_volume_attribute(sd, desc)) {
assert(!"Float2 attribute not support for volumes");
return false;
}
- else {
+ else
+#endif
+ {
float2 fval[3];
fval[0] = primitive_surface_attribute_float2(
- kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ kg, sd, desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
return set_attribute_float2(fval, type, derivatives, val);
}
}
- else if (attr.type == TypeDesc::TypeFloat) {
+ else if (desc.type == NODE_ATTR_FLOAT) {
float fval[3];
- if (primitive_is_volume_attribute(sd, attr.desc)) {
+#ifdef __VOLUME__
+ if (primitive_is_volume_attribute(sd, desc)) {
memset(fval, 0, sizeof(fval));
- fval[0] = primitive_volume_attribute_float(kg, sd, attr.desc);
+ fval[0] = primitive_volume_attribute_float(kg, sd, desc);
}
- else {
+ else
+#endif
+ {
fval[0] = primitive_surface_attribute_float(
- kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ kg, sd, desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
}
return set_attribute_float(fval, type, derivatives, val);
}
- else if (attr.type == TypeDesc::TypeFloat4 || attr.type == TypeRGBA) {
+ else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
float4 fval[3];
- if (primitive_is_volume_attribute(sd, attr.desc)) {
+#ifdef __VOLUME__
+ if (primitive_is_volume_attribute(sd, desc)) {
memset(fval, 0, sizeof(fval));
- fval[0] = primitive_volume_attribute_float4(kg, sd, attr.desc);
+ fval[0] = primitive_volume_attribute_float4(kg, sd, desc);
}
- else {
+ else
+#endif
+ {
fval[0] = primitive_surface_attribute_float4(
- kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ kg, sd, desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
}
return set_attribute_float4(fval, type, derivatives, val);
}
- else {
- return false;
- }
-}
-
-static bool get_mesh_attribute(const KernelGlobalsCPU *kg,
- const ShaderData *sd,
- const OSLGlobals::Attribute &attr,
- const TypeDesc &type,
- bool derivatives,
- void *val)
-{
- if (attr.type == TypeDesc::TypeMatrix) {
- Transform tfm = primitive_attribute_matrix(kg, sd, attr.desc);
+ else if (desc.type == NODE_ATTR_MATRIX) {
+ Transform tfm = primitive_attribute_matrix(kg, desc);
return set_attribute_matrix(tfm, type, val);
}
else {
@@ -817,44 +815,6 @@ static bool get_mesh_attribute(const KernelGlobalsCPU *kg,
}
}
-static bool get_object_attribute(const OSLGlobals::Attribute &attr,
- TypeDesc type,
- bool derivatives,
- void *val)
-{
- if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
- attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) {
- const float *data = (const float *)attr.value.data();
- return set_attribute_float3(make_float3(data[0], data[1], data[2]), type, derivatives, val);
- }
- else if (attr.type == TypeFloat2) {
- const float *data = (const float *)attr.value.data();
- return set_attribute_float2(make_float2(data[0], data[1]), type, derivatives, val);
- }
- else if (attr.type == TypeDesc::TypeFloat) {
- const float *data = (const float *)attr.value.data();
- return set_attribute_float(data[0], type, derivatives, val);
- }
- else if (attr.type == TypeRGBA || attr.type == TypeDesc::TypeFloat4) {
- const float *data = (const float *)attr.value.data();
- return set_attribute_float4(
- make_float4(data[0], data[1], data[2], data[3]), type, derivatives, val);
- }
- else if (attr.type == type) {
- size_t datasize = attr.value.datasize();
-
- memcpy(val, attr.value.data(), datasize);
- if (derivatives) {
- memset((char *)val + datasize, 0, datasize * 2);
- }
-
- return true;
- }
- else {
- return false;
- }
-}
-
bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg,
ShaderData *sd,
ustring name,
@@ -979,6 +939,7 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
float f = ((sd->shader & SHADER_SMOOTH_NORMAL) != 0);
return set_attribute_float(f, type, derivatives, val);
}
+#ifdef __HAIR__
/* Hair Attributes */
else if (name == u_is_curve) {
float f = (sd->type & PRIMITIVE_CURVE) != 0;
@@ -996,6 +957,8 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
float f = curve_random(kg, sd);
return set_attribute_float(f, type, derivatives, val);
}
+#endif
+#ifdef __POINTCLOUD__
/* point attributes */
else if (name == u_is_point) {
float f = (sd->type & PRIMITIVE_POINT) != 0;
@@ -1013,6 +976,7 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
float f = point_random(kg, sd);
return set_attribute_float(f, type, derivatives, val);
}
+#endif
else if (name == u_normal_map_normal) {
if (sd->type & PRIMITIVE_TRIANGLE) {
float3 f = triangle_smooth_normal_unnormalized(kg, sd, sd->Ng, sd->prim, sd->u, sd->v);
@@ -1023,7 +987,7 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
}
}
else {
- return false;
+ return get_background_attribute(kg, sd, name, type, derivatives, val);
}
}
@@ -1131,7 +1095,6 @@ bool OSLRenderServices::get_attribute(
ShaderData *sd, bool derivatives, ustring object_name, TypeDesc type, ustring name, void *val)
{
const KernelGlobalsCPU *kg = sd->osl_globals;
- int prim_type = 0;
int object;
/* lookup of attribute on another object */
@@ -1145,44 +1108,18 @@ bool OSLRenderServices::get_attribute(
}
else {
object = sd->object;
- prim_type = attribute_primitive_type(kg, sd);
-
- if (object == OBJECT_NONE)
- return get_background_attribute(kg, sd, name, type, derivatives, val);
}
/* find attribute on object */
- object = object * ATTR_PRIM_TYPES + prim_type;
- OSLGlobals::AttributeMap &attribute_map = kg->osl->attribute_map[object];
- OSLGlobals::AttributeMap::iterator it = attribute_map.find(name);
-
- if (it != attribute_map.end()) {
- const OSLGlobals::Attribute &attr = it->second;
-
- if (attr.desc.element != ATTR_ELEMENT_OBJECT) {
- /* triangle and vertex attributes */
- if (get_primitive_attribute(kg, sd, attr, type, derivatives, val))
- return true;
- else
- return get_mesh_attribute(kg, sd, attr, type, derivatives, val);
- }
- else {
- /* object attribute */
- return get_object_attribute(attr, type, derivatives, val);
- }
+ const AttributeDescriptor desc = find_attribute(
+ kg, object, sd->prim, object == sd->object ? sd->type : PRIMITIVE_NONE, name.hash());
+ if (desc.offset != ATTR_STD_NOT_FOUND) {
+ return get_object_attribute(kg, sd, desc, type, derivatives, val);
}
else {
/* not found in attribute, check standard object info */
- bool is_std_object_attribute = get_object_standard_attribute(
- kg, sd, name, type, derivatives, val);
-
- if (is_std_object_attribute)
- return true;
-
- return get_background_attribute(kg, sd, name, type, derivatives, val);
+ return get_object_standard_attribute(kg, sd, name, type, derivatives, val);
}
-
- return false;
}
bool OSLRenderServices::get_userdata(
@@ -1667,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;
@@ -1691,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 5862b6a8a2b..83fdfab1217 100644
--- a/intern/cycles/kernel/osl/shader.cpp
+++ b/intern/cycles/kernel/osl/shader.cpp
@@ -13,15 +13,18 @@
#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
-#include "scene/attribute.h"
+#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
@@ -135,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))
@@ -146,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;
- }
}
}
@@ -240,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))
{
@@ -256,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;
- }
}
}
@@ -301,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))
{
@@ -316,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;
}
}
@@ -360,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 */
@@ -386,40 +394,4 @@ void OSLShader::eval_displacement(const KernelGlobalsCPU *kg, const void *state,
sd->P = TO_FLOAT3(globals->P);
}
-/* Attributes */
-
-int OSLShader::find_attribute(const KernelGlobalsCPU *kg,
- const ShaderData *sd,
- uint id,
- AttributeDescriptor *desc)
-{
- /* for OSL, a hash map is used to lookup the attribute by name. */
- int object = sd->object * ATTR_PRIM_TYPES;
-
- OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object];
- ustring stdname(std::string("geom:") +
- std::string(Attribute::standard_name((AttributeStandard)id)));
- OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname);
-
- if (it != attr_map.end()) {
- const OSLGlobals::Attribute &osl_attr = it->second;
- *desc = osl_attr.desc;
-
- if (sd->prim == PRIM_NONE && (AttributeElement)osl_attr.desc.element != ATTR_ELEMENT_MESH) {
- desc->offset = ATTR_STD_NOT_FOUND;
- return ATTR_STD_NOT_FOUND;
- }
-
- /* return result */
- if (osl_attr.desc.element == ATTR_ELEMENT_NONE) {
- desc->offset = ATTR_STD_NOT_FOUND;
- }
- return desc->offset;
- }
- else {
- desc->offset = ATTR_STD_NOT_FOUND;
- return (int)ATTR_STD_NOT_FOUND;
- }
-}
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/shader.h b/intern/cycles/kernel/osl/shader.h
index f0ab49dd6a8..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);
@@ -54,12 +51,6 @@ class OSLShader {
ShaderData *sd,
uint32_t path_flag);
static void eval_displacement(const KernelGlobalsCPU *kg, const void *state, ShaderData *sd);
-
- /* attributes */
- static int find_attribute(const KernelGlobalsCPU *kg,
- const ShaderData *sd,
- uint id,
- AttributeDescriptor *desc);
};
CCL_NAMESPACE_END
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/kernel/types.h b/intern/cycles/kernel/types.h
index 873d594f1f8..bd3791594e0 100644
--- a/intern/cycles/kernel/types.h
+++ b/intern/cycles/kernel/types.h
@@ -655,12 +655,11 @@ typedef struct AttributeDescriptor {
/* For looking up attributes on objects and geometry. */
typedef struct AttributeMap {
- uint id; /* Global unique identifier. */
- uint element; /* AttributeElement. */
- int offset; /* Offset into __attributes global arrays. */
- uint8_t type; /* NodeAttributeType. */
- uint8_t flags; /* AttributeFlag. */
- uint8_t pad[2];
+ uint64_t id; /* Global unique identifier. */
+ int offset; /* Offset into __attributes global arrays. */
+ uint16_t element; /* AttributeElement. */
+ uint8_t type; /* NodeAttributeType. */
+ uint8_t flags; /* AttributeFlag. */
} AttributeMap;
/* Closure data */
diff --git a/intern/cycles/scene/geometry.cpp b/intern/cycles/scene/geometry.cpp
index ae8dcaa43b6..d1a3df851c1 100644
--- a/intern/cycles/scene/geometry.cpp
+++ b/intern/cycles/scene/geometry.cpp
@@ -302,111 +302,32 @@ GeometryManager::~GeometryManager()
{
}
-void GeometryManager::update_osl_attributes(Device *device,
- Scene *scene,
- vector<AttributeRequestSet> &geom_attributes)
+void GeometryManager::update_osl_globals(Device *device, Scene *scene)
{
#ifdef WITH_OSL
- /* for OSL, a hash map is used to lookup the attribute by name. */
OSLGlobals *og = (OSLGlobals *)device->get_cpu_osl_memory();
og->object_name_map.clear();
- og->attribute_map.clear();
og->object_names.clear();
- og->attribute_map.resize(scene->objects.size() * ATTR_PRIM_TYPES);
-
for (size_t i = 0; i < scene->objects.size(); i++) {
/* set object name to object index map */
Object *object = scene->objects[i];
og->object_name_map[object->name] = i;
og->object_names.push_back(object->name);
-
- /* set object attributes */
- foreach (ParamValue &attr, object->attributes) {
- OSLGlobals::Attribute osl_attr;
-
- osl_attr.type = attr.type();
- osl_attr.desc.element = ATTR_ELEMENT_OBJECT;
- osl_attr.value = attr;
- osl_attr.desc.offset = 0;
- osl_attr.desc.flags = 0;
-
- og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][attr.name()] = osl_attr;
- og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][attr.name()] = osl_attr;
- }
-
- /* find geometry attributes */
- size_t j = object->geometry->index;
- assert(j < scene->geometry.size() && scene->geometry[j] == object->geometry);
-
- AttributeRequestSet &attributes = geom_attributes[j];
-
- /* set mesh attributes */
- foreach (AttributeRequest &req, attributes.requests) {
- OSLGlobals::Attribute osl_attr;
-
- if (req.desc.element != ATTR_ELEMENT_NONE) {
- osl_attr.desc = req.desc;
-
- if (req.type == TypeDesc::TypeFloat)
- osl_attr.type = TypeDesc::TypeFloat;
- else if (req.type == TypeDesc::TypeMatrix)
- osl_attr.type = TypeDesc::TypeMatrix;
- else if (req.type == TypeFloat2)
- osl_attr.type = TypeFloat2;
- else if (req.type == TypeRGBA)
- osl_attr.type = TypeRGBA;
- else
- osl_attr.type = TypeDesc::TypeColor;
-
- if (req.std != ATTR_STD_NONE) {
- /* if standard attribute, add lookup by geom: name convention */
- ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
- og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][stdname] = osl_attr;
- }
- else if (req.name != ustring()) {
- /* add lookup by geometry attribute name */
- og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][req.name] = osl_attr;
- }
- }
-
- if (req.subd_desc.element != ATTR_ELEMENT_NONE) {
- osl_attr.desc = req.subd_desc;
-
- if (req.subd_type == TypeDesc::TypeFloat)
- osl_attr.type = TypeDesc::TypeFloat;
- else if (req.subd_type == TypeDesc::TypeMatrix)
- osl_attr.type = TypeDesc::TypeMatrix;
- else if (req.subd_type == TypeFloat2)
- osl_attr.type = TypeFloat2;
- else if (req.subd_type == TypeRGBA)
- osl_attr.type = TypeRGBA;
- else
- osl_attr.type = TypeDesc::TypeColor;
-
- if (req.std != ATTR_STD_NONE) {
- /* if standard attribute, add lookup by geom: name convention */
- ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
- og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][stdname] = osl_attr;
- }
- else if (req.name != ustring()) {
- /* add lookup by geometry attribute name */
- og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][req.name] = osl_attr;
- }
- }
- }
}
#else
(void)device;
(void)scene;
- (void)geom_attributes;
#endif
}
/* Generate a normal attribute map entry from an attribute descriptor. */
-static void emit_attribute_map_entry(
- AttributeMap *attr_map, int index, uint id, TypeDesc type, const AttributeDescriptor &desc)
+static void emit_attribute_map_entry(AttributeMap *attr_map,
+ size_t index,
+ uint64_t id,
+ TypeDesc type,
+ const AttributeDescriptor &desc)
{
attr_map[index].id = id;
attr_map[index].element = desc.element;
@@ -431,7 +352,7 @@ static void emit_attribute_map_entry(
/* Generate an attribute map end marker, optionally including a link to another map.
* Links are used to connect object attribute maps to mesh attribute maps. */
static void emit_attribute_map_terminator(AttributeMap *attr_map,
- int index,
+ size_t index,
bool chain,
uint chain_link)
{
@@ -446,15 +367,8 @@ static void emit_attribute_map_terminator(AttributeMap *attr_map,
/* Generate all necessary attribute map entries from the attribute request. */
static void emit_attribute_mapping(
- AttributeMap *attr_map, int index, Scene *scene, AttributeRequest &req, Geometry *geom)
+ AttributeMap *attr_map, size_t index, uint64_t id, AttributeRequest &req, Geometry *geom)
{
- uint id;
-
- if (req.std == ATTR_STD_NONE)
- id = scene->shader_manager->get_attribute_id(req.name);
- else
- id = scene->shader_manager->get_attribute_id(req.std);
-
emit_attribute_map_entry(attr_map, index, id, req.type, req.desc);
if (geom->is_mesh()) {
@@ -475,12 +389,26 @@ void GeometryManager::update_svm_attributes(Device *,
* attribute, based on a unique shader attribute id. */
/* compute array stride */
- int attr_map_size = 0;
+ size_t attr_map_size = 0;
for (size_t i = 0; i < scene->geometry.size(); i++) {
Geometry *geom = scene->geometry[i];
geom->attr_map_offset = attr_map_size;
- attr_map_size += (geom_attributes[i].size() + 1) * ATTR_PRIM_TYPES;
+
+#ifdef WITH_OSL
+ size_t attr_count = 0;
+ foreach (AttributeRequest &req, geom_attributes[i].requests) {
+ if (req.std != ATTR_STD_NONE &&
+ scene->shader_manager->get_attribute_id(req.std) != (uint64_t)req.std)
+ attr_count += 2;
+ else
+ attr_count += 1;
+ }
+#else
+ const size_t attr_count = geom_attributes[i].size();
+#endif
+
+ attr_map_size += (attr_count + 1) * ATTR_PRIM_TYPES;
}
for (size_t i = 0; i < scene->objects.size(); i++) {
@@ -512,11 +440,26 @@ void GeometryManager::update_svm_attributes(Device *,
AttributeRequestSet &attributes = geom_attributes[i];
/* set geometry attributes */
- int index = geom->attr_map_offset;
+ size_t index = geom->attr_map_offset;
foreach (AttributeRequest &req, attributes.requests) {
- emit_attribute_mapping(attr_map, index, scene, req, geom);
+ uint64_t id;
+ if (req.std == ATTR_STD_NONE)
+ id = scene->shader_manager->get_attribute_id(req.name);
+ else
+ id = scene->shader_manager->get_attribute_id(req.std);
+
+ emit_attribute_mapping(attr_map, index, id, req, geom);
index += ATTR_PRIM_TYPES;
+
+#ifdef WITH_OSL
+ /* Some standard attributes are explicitly referenced via their standard ID, so add those
+ * again in case they were added under a different attribute ID. */
+ if (req.std != ATTR_STD_NONE && id != (uint64_t)req.std) {
+ emit_attribute_mapping(attr_map, index, (uint64_t)req.std, req, geom);
+ index += ATTR_PRIM_TYPES;
+ }
+#endif
}
emit_attribute_map_terminator(attr_map, index, false, 0);
@@ -528,10 +471,16 @@ void GeometryManager::update_svm_attributes(Device *,
/* set object attributes */
if (attributes.size() > 0) {
- int index = object->attr_map_offset;
+ size_t index = object->attr_map_offset;
foreach (AttributeRequest &req, attributes.requests) {
- emit_attribute_mapping(attr_map, index, scene, req, object->geometry);
+ uint64_t id;
+ if (req.std == ATTR_STD_NONE)
+ id = scene->shader_manager->get_attribute_id(req.name);
+ else
+ id = scene->shader_manager->get_attribute_id(req.std);
+
+ emit_attribute_mapping(attr_map, index, id, req, object->geometry);
index += ATTR_PRIM_TYPES;
}
@@ -982,7 +931,7 @@ void GeometryManager::device_update_attributes(Device *device,
/* create attribute lookup maps */
if (scene->shader_manager->use_osl())
- update_osl_attributes(device, scene, geom_attributes);
+ update_osl_globals(device, scene);
update_svm_attributes(device, dscene, scene, geom_attributes, object_attributes);
@@ -2188,7 +2137,6 @@ void GeometryManager::device_free(Device *device, DeviceScene *dscene, bool forc
if (og) {
og->object_name_map.clear();
- og->attribute_map.clear();
og->object_names.clear();
}
#else
diff --git a/intern/cycles/scene/geometry.h b/intern/cycles/scene/geometry.h
index 6210a64509a..8a1bdc33a6f 100644
--- a/intern/cycles/scene/geometry.h
+++ b/intern/cycles/scene/geometry.h
@@ -219,9 +219,7 @@ class GeometryManager {
void create_volume_mesh(const Scene *scene, Volume *volume, Progress &progress);
/* Attributes */
- void update_osl_attributes(Device *device,
- Scene *scene,
- vector<AttributeRequestSet> &geom_attributes);
+ void update_osl_globals(Device *device, Scene *scene);
void update_svm_attributes(Device *device,
DeviceScene *dscene,
Scene *scene,
diff --git a/intern/cycles/scene/osl.cpp b/intern/cycles/scene/osl.cpp
index f5ee0c0f1d3..f0246b5b40e 100644
--- a/intern/cycles/scene/osl.cpp
+++ b/intern/cycles/scene/osl.cpp
@@ -78,6 +78,18 @@ void OSLShaderManager::reset(Scene * /*scene*/)
shading_system_init();
}
+uint64_t OSLShaderManager::get_attribute_id(ustring name)
+{
+ return name.hash();
+}
+
+uint64_t OSLShaderManager::get_attribute_id(AttributeStandard std)
+{
+ /* if standard attribute, use geom: name convention */
+ ustring stdname(string("geom:") + string(Attribute::standard_name(std)));
+ return stdname.hash();
+}
+
void OSLShaderManager::device_update_specific(Device *device,
DeviceScene *dscene,
Scene *scene,
@@ -286,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();
}
diff --git a/intern/cycles/scene/osl.h b/intern/cycles/scene/osl.h
index bf27069b1b1..76c6bd96ce1 100644
--- a/intern/cycles/scene/osl.h
+++ b/intern/cycles/scene/osl.h
@@ -66,6 +66,9 @@ class OSLShaderManager : public ShaderManager {
return true;
}
+ uint64_t get_attribute_id(ustring name) override;
+ uint64_t get_attribute_id(AttributeStandard std) override;
+
void device_update_specific(Device *device,
DeviceScene *dscene,
Scene *scene,
diff --git a/intern/cycles/scene/shader.cpp b/intern/cycles/scene/shader.cpp
index bd647ab55e7..96a8f40bbad 100644
--- a/intern/cycles/scene/shader.cpp
+++ b/intern/cycles/scene/shader.cpp
@@ -414,7 +414,7 @@ ShaderManager *ShaderManager::create(int shadingsystem)
return manager;
}
-uint ShaderManager::get_attribute_id(ustring name)
+uint64_t ShaderManager::get_attribute_id(ustring name)
{
thread_scoped_spin_lock lock(attribute_lock_);
@@ -424,14 +424,14 @@ uint ShaderManager::get_attribute_id(ustring name)
if (it != unique_attribute_id.end())
return it->second;
- uint id = (uint)ATTR_STD_NUM + unique_attribute_id.size();
+ uint64_t id = ATTR_STD_NUM + unique_attribute_id.size();
unique_attribute_id[name] = id;
return id;
}
-uint ShaderManager::get_attribute_id(AttributeStandard std)
+uint64_t ShaderManager::get_attribute_id(AttributeStandard std)
{
- return (uint)std;
+ return (uint64_t)std;
}
int ShaderManager::get_shader_id(Shader *shader, bool smooth)
diff --git a/intern/cycles/scene/shader.h b/intern/cycles/scene/shader.h
index 274bb9b4fa1..2670776aca4 100644
--- a/intern/cycles/scene/shader.h
+++ b/intern/cycles/scene/shader.h
@@ -192,8 +192,8 @@ class ShaderManager {
void device_free_common(Device *device, DeviceScene *dscene, Scene *scene);
/* get globally unique id for a type of attribute */
- uint get_attribute_id(ustring name);
- uint get_attribute_id(AttributeStandard std);
+ virtual uint64_t get_attribute_id(ustring name);
+ virtual uint64_t get_attribute_id(AttributeStandard std);
/* get shader id for mesh faces */
int get_shader_id(Shader *shader, bool smooth = false);
@@ -223,7 +223,7 @@ class ShaderManager {
uint32_t update_flags;
- typedef unordered_map<ustring, uint, ustringHash> AttributeIDMap;
+ typedef unordered_map<ustring, uint64_t, ustringHash> AttributeIDMap;
AttributeIDMap unique_attribute_id;
static thread_mutex lookup_table_mutex;