diff options
author | Jeroen Bakker <j.bakker@atmind.nl> | 2022-09-09 22:09:51 +0300 |
---|---|---|
committer | Jeroen Bakker <j.bakker@atmind.nl> | 2022-09-09 22:09:51 +0300 |
commit | 5082fd5e63737bf8cb76478d143647e1907d13f4 (patch) | |
tree | 8736fcf031cdee3a7c10d0a7ebc60578f81dea06 /intern/cycles | |
parent | b3400d012a33fa774a20893993b3e7ed9b9f1f97 (diff) | |
parent | 1e1e9014cfc9f47d8496dd283a1cccae0ce29552 (diff) |
Merge branch 'master' into temp-T73411-add-scene-parameters
Diffstat (limited to 'intern/cycles')
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), ¶ms); - - if (bsdf) { - bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8); - - if (bsdf->colors) { - for (int i = 0; i < 8; i++) - bsdf->colors[i] = TO_FLOAT3(colors[i]); - - sd->flag |= bsdf_diffuse_ramp_setup(bsdf); - } - } - } -}; - -ClosureParam *closure_bsdf_diffuse_ramp_params() -{ - static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(DiffuseRampClosure, params.N), - CLOSURE_COLOR_ARRAY_PARAM(DiffuseRampClosure, colors, 8), - CLOSURE_STRING_KEYPARAM(DiffuseRampClosure, label, "label"), - CLOSURE_FINISH_PARAM(DiffuseRampClosure)}; - return params; -} - -CCLOSURE_PREPARE(closure_bsdf_diffuse_ramp_prepare, DiffuseRampClosure) - -CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp deleted file mode 100644 index 6f54a96e542..00000000000 --- a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Adapted from Open Shading Language - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011-2022 Blender Foundation. */ - -#include <OpenImageIO/fmath.h> - -#include <OSL/genclosure.h> - -#include "kernel/device/cpu/compat.h" -#include "kernel/osl/closures.h" - -// clang-format off -#include "kernel/device/cpu/compat.h" -#include "kernel/device/cpu/globals.h" - -#include "kernel/types.h" -#include "kernel/closure/alloc.h" -#include "kernel/closure/bsdf_phong_ramp.h" -#include "kernel/closure/bsdf_util.h" - -#include "kernel/util/color.h" -// clang-format on - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -class PhongRampClosure : public CBSDFClosure { - public: - PhongRampBsdf params; - Color3 colors[8]; - - void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - PhongRampBsdf *bsdf = (PhongRampBsdf *)bsdf_alloc_osl( - sd, sizeof(PhongRampBsdf), rgb_to_spectrum(weight), ¶ms); - - if (bsdf) { - bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8); - - if (bsdf->colors) { - for (int i = 0; i < 8; i++) - bsdf->colors[i] = TO_FLOAT3(colors[i]); - - sd->flag |= bsdf_phong_ramp_setup(bsdf); - } - } - } -}; - -ClosureParam *closure_bsdf_phong_ramp_params() -{ - static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(PhongRampClosure, params.N), - CLOSURE_FLOAT_PARAM(PhongRampClosure, params.exponent), - CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, colors, 8), - CLOSURE_STRING_KEYPARAM(PhongRampClosure, label, "label"), - CLOSURE_FINISH_PARAM(PhongRampClosure)}; - return params; -} - -CCLOSURE_PREPARE(closure_bsdf_phong_ramp_prepare, PhongRampClosure) - -CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/bssrdf.cpp b/intern/cycles/kernel/osl/bssrdf.cpp deleted file mode 100644 index 3054946ba5a..00000000000 --- a/intern/cycles/kernel/osl/bssrdf.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Adapted from Open Shading Language - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011-2022 Blender Foundation. */ - -#include <OSL/genclosure.h> - -#include "kernel/device/cpu/compat.h" -#include "kernel/osl/closures.h" - -// clang-format off -#include "kernel/device/cpu/compat.h" -#include "kernel/device/cpu/globals.h" - -#include "kernel/types.h" - -#include "kernel/closure/alloc.h" -#include "kernel/closure/bsdf_util.h" -#include "kernel/closure/bsdf_diffuse.h" -#include "kernel/closure/bsdf_principled_diffuse.h" -#include "kernel/closure/bssrdf.h" - -#include "kernel/util/color.h" -// clang-format on - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -static ustring u_burley("burley"); -static ustring u_random_walk_fixed_radius("random_walk_fixed_radius"); -static ustring u_random_walk("random_walk"); - -class CBSSRDFClosure : public CClosurePrimitive { - public: - Bssrdf params; - float ior; - ustring method; - - CBSSRDFClosure() - { - params.roughness = FLT_MAX; - params.anisotropy = 1.0f; - ior = 1.4f; - } - - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - if (method == u_burley) { - alloc(sd, path_flag, weight, CLOSURE_BSSRDF_BURLEY_ID); - } - else if (method == u_random_walk_fixed_radius) { - alloc(sd, path_flag, weight, CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID); - } - else if (method == u_random_walk) { - alloc(sd, path_flag, weight, CLOSURE_BSSRDF_RANDOM_WALK_ID); - } - } - - void alloc(ShaderData *sd, uint32_t path_flag, float3 weight, ClosureType type) - { - Bssrdf *bssrdf = bssrdf_alloc(sd, rgb_to_spectrum(weight)); - - if (bssrdf) { - /* disable in case of diffuse ancestor, can't see it well then and - * adds considerably noise due to probabilities of continuing path - * getting lower and lower */ - if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR) { - params.radius = zero_spectrum(); - } - - /* create one closure per color channel */ - bssrdf->radius = params.radius; - bssrdf->albedo = params.albedo; - bssrdf->N = params.N; - bssrdf->roughness = params.roughness; - bssrdf->anisotropy = clamp(params.anisotropy, 0.0f, 0.9f); - sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type, clamp(ior, 1.01f, 3.8f)); - } - } -}; - -ClosureParam *closure_bssrdf_params() -{ - static ClosureParam params[] = { - CLOSURE_STRING_PARAM(CBSSRDFClosure, method), - CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.N), - CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.radius), - CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.albedo), - CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, params.roughness, "roughness"), - CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, ior, "ior"), - CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, params.anisotropy, "anisotropy"), - CLOSURE_STRING_KEYPARAM(CBSSRDFClosure, label, "label"), - CLOSURE_FINISH_PARAM(CBSSRDFClosure)}; - return params; -} - -CCLOSURE_PREPARE(closure_bssrdf_prepare, CBSSRDFClosure) - -CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/closures.cpp b/intern/cycles/kernel/osl/closures.cpp index 8766fb73dbb..604d672063b 100644 --- a/intern/cycles/kernel/osl/closures.cpp +++ b/intern/cycles/kernel/osl/closures.cpp @@ -9,999 +9,48 @@ #include <OSL/genclosure.h> #include <OSL/oslclosure.h> -#include "kernel/osl/closures.h" -#include "kernel/osl/shader.h" +#include "kernel/types.h" + +#include "kernel/osl/globals.h" +#include "kernel/osl/services.h" #include "util/math.h" #include "util/param.h" -// clang-format off #include "kernel/device/cpu/compat.h" #include "kernel/device/cpu/globals.h" -#include "kernel/types.h" - -#include "kernel/closure/alloc.h" -#include "kernel/closure/bsdf_util.h" -#include "kernel/closure/bsdf_ashikhmin_velvet.h" -#include "kernel/closure/bsdf_diffuse.h" -#include "kernel/closure/bsdf_microfacet.h" -#include "kernel/closure/bsdf_microfacet_multi.h" -#include "kernel/closure/bsdf_oren_nayar.h" -#include "kernel/closure/bsdf_reflection.h" -#include "kernel/closure/bsdf_refraction.h" -#include "kernel/closure/bsdf_transparent.h" -#include "kernel/closure/bsdf_ashikhmin_shirley.h" -#include "kernel/closure/bsdf_toon.h" -#include "kernel/closure/bsdf_hair.h" -#include "kernel/closure/bsdf_hair_principled.h" -#include "kernel/closure/bsdf_principled_diffuse.h" -#include "kernel/closure/bsdf_principled_sheen.h" -#include "kernel/closure/volume.h" - -#include "kernel/util/color.h" -// clang-format on +#include "kernel/osl/types.h" +#include "kernel/osl/closures_setup.h" CCL_NAMESPACE_BEGIN -using namespace OSL; - -/* BSDF class definitions */ - -BSDF_CLOSURE_CLASS_BEGIN(Diffuse, diffuse, DiffuseBsdf, LABEL_DIFFUSE) - BSDF_CLOSURE_FLOAT3_PARAM(DiffuseClosure, params.N) -BSDF_CLOSURE_CLASS_END(Diffuse, diffuse) - -BSDF_CLOSURE_CLASS_BEGIN(Translucent, translucent, DiffuseBsdf, LABEL_DIFFUSE) - BSDF_CLOSURE_FLOAT3_PARAM(TranslucentClosure, params.N) -BSDF_CLOSURE_CLASS_END(Translucent, translucent) - -BSDF_CLOSURE_CLASS_BEGIN(OrenNayar, oren_nayar, OrenNayarBsdf, LABEL_DIFFUSE) - BSDF_CLOSURE_FLOAT3_PARAM(OrenNayarClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(OrenNayarClosure, params.roughness) -BSDF_CLOSURE_CLASS_END(OrenNayar, oren_nayar) - -BSDF_CLOSURE_CLASS_BEGIN(Reflection, reflection, MicrofacetBsdf, LABEL_SINGULAR) - BSDF_CLOSURE_FLOAT3_PARAM(ReflectionClosure, params.N) -BSDF_CLOSURE_CLASS_END(Reflection, reflection) - -BSDF_CLOSURE_CLASS_BEGIN(Refraction, refraction, MicrofacetBsdf, LABEL_SINGULAR) - BSDF_CLOSURE_FLOAT3_PARAM(RefractionClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(RefractionClosure, params.ior) -BSDF_CLOSURE_CLASS_END(Refraction, refraction) - -BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, VelvetBsdf, LABEL_DIFFUSE) - BSDF_CLOSURE_FLOAT3_PARAM(AshikhminVelvetClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, params.sigma) -BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet) - -BSDF_CLOSURE_CLASS_BEGIN(AshikhminShirley, - ashikhmin_shirley, - MicrofacetBsdf, - LABEL_GLOSSY | LABEL_REFLECT) - BSDF_CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.N) - BSDF_CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.T) - BSDF_CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_x) - BSDF_CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_y) -BSDF_CLOSURE_CLASS_END(AshikhminShirley, ashikhmin_shirley) - -BSDF_CLOSURE_CLASS_BEGIN(DiffuseToon, diffuse_toon, ToonBsdf, LABEL_DIFFUSE) - BSDF_CLOSURE_FLOAT3_PARAM(DiffuseToonClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(DiffuseToonClosure, params.size) - BSDF_CLOSURE_FLOAT_PARAM(DiffuseToonClosure, params.smooth) -BSDF_CLOSURE_CLASS_END(DiffuseToon, diffuse_toon) - -BSDF_CLOSURE_CLASS_BEGIN(GlossyToon, glossy_toon, ToonBsdf, LABEL_GLOSSY) - BSDF_CLOSURE_FLOAT3_PARAM(GlossyToonClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(GlossyToonClosure, params.size) - BSDF_CLOSURE_FLOAT_PARAM(GlossyToonClosure, params.smooth) -BSDF_CLOSURE_CLASS_END(GlossyToon, glossy_toon) - -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXIsotropic, - microfacet_ggx_isotropic, - MicrofacetBsdf, - LABEL_GLOSSY | LABEL_REFLECT) - BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetGGXIsotropicClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetGGXIsotropicClosure, params.alpha_x) -BSDF_CLOSURE_CLASS_END(MicrofacetGGXIsotropic, microfacet_ggx_isotropic) - -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX, - microfacet_ggx, - MicrofacetBsdf, - LABEL_GLOSSY | LABEL_REFLECT) - BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, params.N) - BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, params.T) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, params.alpha_x) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, params.alpha_y) -BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx) - -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannIsotropic, - microfacet_beckmann_isotropic, - MicrofacetBsdf, - LABEL_GLOSSY | LABEL_REFLECT) - BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannIsotropicClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetBeckmannIsotropicClosure, params.alpha_x) -BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannIsotropic, microfacet_beckmann_isotropic) - -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann, - microfacet_beckmann, - MicrofacetBsdf, - LABEL_GLOSSY | LABEL_REFLECT) - BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, params.N) - BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, params.T) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, params.alpha_x) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, params.alpha_y) -BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann) - -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction, - microfacet_ggx_refraction, - MicrofacetBsdf, - LABEL_GLOSSY | LABEL_TRANSMIT) - BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetGGXRefractionClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, params.alpha_x) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, params.ior) -BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction) - -BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction, - microfacet_beckmann_refraction, - MicrofacetBsdf, - LABEL_GLOSSY | LABEL_TRANSMIT) - BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannRefractionClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, params.alpha_x) - BSDF_CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, params.ior) -BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction) - -BSDF_CLOSURE_CLASS_BEGIN(HairReflection, hair_reflection, HairBsdf, LABEL_GLOSSY) - BSDF_CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.roughness1) - BSDF_CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.roughness2) - BSDF_CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.T) - BSDF_CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.offset) -BSDF_CLOSURE_CLASS_END(HairReflection, hair_reflection) - -BSDF_CLOSURE_CLASS_BEGIN(HairTransmission, hair_transmission, HairBsdf, LABEL_GLOSSY) - BSDF_CLOSURE_FLOAT3_PARAM(HairTransmissionClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(HairTransmissionClosure, params.roughness1) - BSDF_CLOSURE_FLOAT_PARAM(HairTransmissionClosure, params.roughness2) - BSDF_CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.T) - BSDF_CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.offset) -BSDF_CLOSURE_CLASS_END(HairTransmission, hair_transmission) - -BSDF_CLOSURE_CLASS_BEGIN(PrincipledDiffuse, - principled_diffuse, - PrincipledDiffuseBsdf, - LABEL_DIFFUSE) - BSDF_CLOSURE_FLOAT3_PARAM(PrincipledDiffuseClosure, params.N) - BSDF_CLOSURE_FLOAT_PARAM(PrincipledDiffuseClosure, params.roughness) -BSDF_CLOSURE_CLASS_END(PrincipledDiffuse, principled_diffuse) - -class PrincipledSheenClosure : public CBSDFClosure { - public: - PrincipledSheenBsdf params; - - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - if (!skip(sd, path_flag, LABEL_DIFFUSE)) { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - PrincipledSheenBsdf *bsdf = (PrincipledSheenBsdf *)bsdf_alloc_osl( - sd, sizeof(PrincipledSheenBsdf), rgb_to_spectrum(weight), ¶ms); - sd->flag |= (bsdf) ? bsdf_principled_sheen_setup(sd, bsdf) : 0; - } - } -}; - -static ClosureParam *bsdf_principled_sheen_params() -{ - static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(PrincipledSheenClosure, params.N), - CLOSURE_STRING_KEYPARAM(PrincipledSheenClosure, label, "label"), - CLOSURE_FINISH_PARAM(PrincipledSheenClosure)}; - return params; -} - -CCLOSURE_PREPARE_STATIC(closure_bsdf_principled_sheen_prepare, PrincipledSheenClosure) - -/* PRINCIPLED HAIR BSDF */ -class PrincipledHairClosure : public CBSDFClosure { - public: - PrincipledHairBSDF params; - - PrincipledHairBSDF *alloc(ShaderData *sd, uint32_t path_flag, float3 weight) - { - PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)bsdf_alloc_osl( - sd, sizeof(PrincipledHairBSDF), rgb_to_spectrum(weight), ¶ms); - if (!bsdf) { - return NULL; - } - - PrincipledHairExtra *extra = (PrincipledHairExtra *)closure_alloc_extra( - sd, sizeof(PrincipledHairExtra)); - if (!extra) { - return NULL; - } - - bsdf->extra = extra; - return bsdf; - } - - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - if (!skip(sd, path_flag, LABEL_GLOSSY)) { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - sd->flag |= (bsdf) ? bsdf_principled_hair_setup(sd, bsdf) : 0; - } - } -}; - -static ClosureParam *closure_bsdf_principled_hair_params() -{ - static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(PrincipledHairClosure, params.N), - CLOSURE_FLOAT3_PARAM(PrincipledHairClosure, params.sigma), - CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.v), - CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.s), - CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.m0_roughness), - CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.alpha), - CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.eta), - CLOSURE_STRING_KEYPARAM(PrincipledHairClosure, label, "label"), - CLOSURE_FINISH_PARAM(PrincipledHairClosure)}; - - return params; -} - -CCLOSURE_PREPARE(closure_bsdf_principled_hair_prepare, PrincipledHairClosure) - -/* DISNEY PRINCIPLED CLEARCOAT */ -class PrincipledClearcoatClosure : public CBSDFClosure { - public: - MicrofacetBsdf params; - float clearcoat, clearcoat_roughness; - - MicrofacetBsdf *alloc(ShaderData *sd, uint32_t path_flag, float3 weight) - { - MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), ¶ms); - if (!bsdf) { - return NULL; - } - - MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); - if (!extra) { - return NULL; - } - - bsdf->T = zero_float3(); - bsdf->extra = extra; - bsdf->ior = 1.5f; - bsdf->alpha_x = clearcoat_roughness; - bsdf->alpha_y = clearcoat_roughness; - bsdf->extra->color = zero_spectrum(); - bsdf->extra->cspec0 = make_spectrum(0.04f); - bsdf->extra->clearcoat = clearcoat; - return bsdf; - } - - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd); - } -}; - -ClosureParam *closure_bsdf_principled_clearcoat_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT3_PARAM(PrincipledClearcoatClosure, params.N), - CLOSURE_FLOAT_PARAM(PrincipledClearcoatClosure, clearcoat), - CLOSURE_FLOAT_PARAM(PrincipledClearcoatClosure, clearcoat_roughness), - CLOSURE_STRING_KEYPARAM(PrincipledClearcoatClosure, label, "label"), - CLOSURE_FINISH_PARAM(PrincipledClearcoatClosure)}; - return params; -} -CCLOSURE_PREPARE(closure_bsdf_principled_clearcoat_prepare, PrincipledClearcoatClosure) - /* Registration */ -static void register_closure(OSL::ShadingSystem *ss, - const char *name, - int id, - OSL::ClosureParam *params, - OSL::PrepareClosureFunc prepare) -{ - /* optimization: it's possible to not use a prepare function at all and - * only initialize the actual class when accessing the closure component - * data, but then we need to map the id to the class somehow */ -#if OSL_LIBRARY_VERSION_CODE >= 10900 - ss->register_closure(name, id, params, prepare, NULL); -#else - ss->register_closure(name, id, params, prepare, NULL, 16); -#endif -} - -void OSLShader::register_closures(OSLShadingSystem *ss_) -{ - OSL::ShadingSystem *ss = (OSL::ShadingSystem *)ss_; - int id = 0; - - register_closure(ss, "diffuse", id++, bsdf_diffuse_params(), bsdf_diffuse_prepare); - register_closure(ss, "oren_nayar", id++, bsdf_oren_nayar_params(), bsdf_oren_nayar_prepare); - register_closure(ss, "translucent", id++, bsdf_translucent_params(), bsdf_translucent_prepare); - register_closure(ss, "reflection", id++, bsdf_reflection_params(), bsdf_reflection_prepare); - register_closure(ss, "refraction", id++, bsdf_refraction_params(), bsdf_refraction_prepare); - register_closure(ss, - "transparent", - id++, - closure_bsdf_transparent_params(), - closure_bsdf_transparent_prepare); - - register_closure( - ss, "microfacet", id++, closure_bsdf_microfacet_params(), closure_bsdf_microfacet_prepare); - register_closure(ss, - "microfacet_ggx", - id++, - bsdf_microfacet_ggx_isotropic_params(), - bsdf_microfacet_ggx_isotropic_prepare); - register_closure( - ss, "microfacet_ggx_aniso", id++, bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare); - register_closure(ss, - "microfacet_ggx_refraction", - id++, - bsdf_microfacet_ggx_refraction_params(), - bsdf_microfacet_ggx_refraction_prepare); - register_closure(ss, - "microfacet_multi_ggx", - id++, - closure_bsdf_microfacet_multi_ggx_params(), - closure_bsdf_microfacet_multi_ggx_prepare); - register_closure(ss, - "microfacet_multi_ggx_glass", - id++, - closure_bsdf_microfacet_multi_ggx_glass_params(), - closure_bsdf_microfacet_multi_ggx_glass_prepare); - register_closure(ss, - "microfacet_multi_ggx_aniso", - id++, - closure_bsdf_microfacet_multi_ggx_aniso_params(), - closure_bsdf_microfacet_multi_ggx_aniso_prepare); - register_closure(ss, - "microfacet_ggx_fresnel", - id++, - closure_bsdf_microfacet_ggx_fresnel_params(), - closure_bsdf_microfacet_ggx_fresnel_prepare); - register_closure(ss, - "microfacet_ggx_aniso_fresnel", - id++, - closure_bsdf_microfacet_ggx_aniso_fresnel_params(), - closure_bsdf_microfacet_ggx_aniso_fresnel_prepare); - register_closure(ss, - "microfacet_multi_ggx_fresnel", - id++, - closure_bsdf_microfacet_multi_ggx_fresnel_params(), - closure_bsdf_microfacet_multi_ggx_fresnel_prepare); - register_closure(ss, - "microfacet_multi_ggx_glass_fresnel", - id++, - closure_bsdf_microfacet_multi_ggx_glass_fresnel_params(), - closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare); - register_closure(ss, - "microfacet_multi_ggx_aniso_fresnel", - id++, - closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params(), - closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare); - register_closure(ss, - "microfacet_beckmann", - id++, - bsdf_microfacet_beckmann_isotropic_params(), - bsdf_microfacet_beckmann_isotropic_prepare); - register_closure(ss, - "microfacet_beckmann_aniso", - id++, - bsdf_microfacet_beckmann_params(), - bsdf_microfacet_beckmann_prepare); - register_closure(ss, - "microfacet_beckmann_refraction", - id++, - bsdf_microfacet_beckmann_refraction_params(), - bsdf_microfacet_beckmann_refraction_prepare); - register_closure(ss, - "ashikhmin_shirley", - id++, - bsdf_ashikhmin_shirley_params(), - bsdf_ashikhmin_shirley_prepare); - register_closure( - ss, "ashikhmin_velvet", id++, bsdf_ashikhmin_velvet_params(), bsdf_ashikhmin_velvet_prepare); - register_closure( - ss, "diffuse_toon", id++, bsdf_diffuse_toon_params(), bsdf_diffuse_toon_prepare); - register_closure(ss, "glossy_toon", id++, bsdf_glossy_toon_params(), bsdf_glossy_toon_prepare); - register_closure(ss, - "principled_diffuse", - id++, - bsdf_principled_diffuse_params(), - bsdf_principled_diffuse_prepare); - register_closure(ss, - "principled_sheen", - id++, - bsdf_principled_sheen_params(), - closure_bsdf_principled_sheen_prepare); - register_closure(ss, - "principled_clearcoat", - id++, - closure_bsdf_principled_clearcoat_params(), - closure_bsdf_principled_clearcoat_prepare); - - register_closure(ss, "emission", id++, closure_emission_params(), closure_emission_prepare); - register_closure( - ss, "background", id++, closure_background_params(), closure_background_prepare); - register_closure(ss, "holdout", id++, closure_holdout_params(), closure_holdout_prepare); - register_closure(ss, - "diffuse_ramp", - id++, - closure_bsdf_diffuse_ramp_params(), - closure_bsdf_diffuse_ramp_prepare); - register_closure( - ss, "phong_ramp", id++, closure_bsdf_phong_ramp_params(), closure_bsdf_phong_ramp_prepare); - register_closure(ss, "bssrdf", id++, closure_bssrdf_params(), closure_bssrdf_prepare); - - register_closure( - ss, "hair_reflection", id++, bsdf_hair_reflection_params(), bsdf_hair_reflection_prepare); - register_closure(ss, - "hair_transmission", - id++, - bsdf_hair_transmission_params(), - bsdf_hair_transmission_prepare); - - register_closure(ss, - "principled_hair", - id++, - closure_bsdf_principled_hair_params(), - closure_bsdf_principled_hair_prepare); - - register_closure(ss, - "henyey_greenstein", - id++, - closure_henyey_greenstein_params(), - closure_henyey_greenstein_prepare); - register_closure( - ss, "absorption", id++, closure_absorption_params(), closure_absorption_prepare); -} - -/* BSDF Closure */ - -bool CBSDFClosure::skip(const ShaderData *sd, uint32_t path_flag, int scattering) -{ - /* caustic options */ - if ((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) { - const KernelGlobalsCPU *kg = sd->osl_globals; - - if ((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) || - (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) { - return true; - } - } - - return false; -} - -/* Standard Microfacet Closure */ - -class MicrofacetClosure : public CBSDFClosure { - public: - MicrofacetBsdf params; - ustring distribution; - int refract; - - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - static ustring u_ggx("ggx"); - static ustring u_default("default"); - - const int label = (refract) ? LABEL_TRANSMIT : LABEL_REFLECT; - if (skip(sd, path_flag, LABEL_GLOSSY | label)) { - return; - } - - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), ¶ms); - - if (!bsdf) { - return; - } - - /* GGX */ - if (distribution == u_ggx || distribution == u_default) { - if (!refract) { - if (params.alpha_x == params.alpha_y) { - /* Isotropic */ - sd->flag |= bsdf_microfacet_ggx_isotropic_setup(bsdf); - } - else { - /* Anisotropic */ - sd->flag |= bsdf_microfacet_ggx_setup(bsdf); - } - } - else { - sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); - } - } - /* Beckmann */ - else { - if (!refract) { - if (params.alpha_x == params.alpha_y) { - /* Isotropic */ - sd->flag |= bsdf_microfacet_beckmann_isotropic_setup(bsdf); - } - else { - /* Anisotropic */ - sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); - } - } - else { - sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf); - } - } - } -}; - -ClosureParam *closure_bsdf_microfacet_params() -{ - static ClosureParam params[] = {CLOSURE_STRING_PARAM(MicrofacetClosure, distribution), - CLOSURE_FLOAT3_PARAM(MicrofacetClosure, params.N), - CLOSURE_FLOAT3_PARAM(MicrofacetClosure, params.T), - CLOSURE_FLOAT_PARAM(MicrofacetClosure, params.alpha_x), - CLOSURE_FLOAT_PARAM(MicrofacetClosure, params.alpha_y), - CLOSURE_FLOAT_PARAM(MicrofacetClosure, params.ior), - CLOSURE_INT_PARAM(MicrofacetClosure, refract), - CLOSURE_STRING_KEYPARAM(MicrofacetClosure, label, "label"), - CLOSURE_FINISH_PARAM(MicrofacetClosure)}; - - return params; -} -CCLOSURE_PREPARE(closure_bsdf_microfacet_prepare, MicrofacetClosure) - -/* GGX closures with Fresnel */ - -class MicrofacetFresnelClosure : public CBSDFClosure { - public: - MicrofacetBsdf params; - float3 color; - float3 cspec0; - - MicrofacetBsdf *alloc(ShaderData *sd, uint32_t path_flag, float3 weight) - { - /* Technically, the MultiGGX Glass closure may also transmit. However, - * since this is set statically and only used for caustic flags, this - * is probably as good as it gets. */ - if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { - return NULL; - } - - MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), ¶ms); - if (!bsdf) { - return NULL; - } - - MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); - if (!extra) { - return NULL; - } - - bsdf->extra = extra; - bsdf->extra->color = rgb_to_spectrum(color); - bsdf->extra->cspec0 = rgb_to_spectrum(cspec0); - bsdf->extra->clearcoat = 0.0f; - return bsdf; - } -}; - -class MicrofacetGGXFresnelClosure : public MicrofacetFresnelClosure { - public: - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - bsdf->T = zero_float3(); - bsdf->alpha_y = bsdf->alpha_x; - sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd); - } -}; - -ClosureParam *closure_bsdf_microfacet_ggx_fresnel_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.N), - CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_x), - CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.ior), - CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, color), - CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, cspec0), - CLOSURE_STRING_KEYPARAM(MicrofacetGGXFresnelClosure, label, "label"), - CLOSURE_FINISH_PARAM(MicrofacetGGXFresnelClosure)}; - return params; -} -CCLOSURE_PREPARE(closure_bsdf_microfacet_ggx_fresnel_prepare, MicrofacetGGXFresnelClosure); - -class MicrofacetGGXAnisoFresnelClosure : public MicrofacetFresnelClosure { - public: - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd); - } -}; - -ClosureParam *closure_bsdf_microfacet_ggx_aniso_fresnel_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.N), - CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.T), - CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_x), - CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_y), - CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.ior), - CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, color), - CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, cspec0), - CLOSURE_STRING_KEYPARAM(MicrofacetGGXFresnelClosure, label, "label"), - CLOSURE_FINISH_PARAM(MicrofacetGGXFresnelClosure)}; - return params; -} -CCLOSURE_PREPARE(closure_bsdf_microfacet_ggx_aniso_fresnel_prepare, - MicrofacetGGXAnisoFresnelClosure); - -/* Multiscattering GGX closures */ - -class MicrofacetMultiClosure : public CBSDFClosure { - public: - MicrofacetBsdf params; - float3 color; - - MicrofacetBsdf *alloc(ShaderData *sd, uint32_t path_flag, float3 weight) - { - /* Technically, the MultiGGX closure may also transmit. However, - * since this is set statically and only used for caustic flags, this - * is probably as good as it gets. */ - if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { - return NULL; - } - - MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), ¶ms); - if (!bsdf) { - return NULL; - } - - MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); - if (!extra) { - return NULL; - } - - bsdf->extra = extra; - bsdf->extra->color = rgb_to_spectrum(color); - bsdf->extra->cspec0 = zero_spectrum(); - bsdf->extra->clearcoat = 0.0f; - return bsdf; - } -}; - -class MicrofacetMultiGGXClosure : public MicrofacetMultiClosure { - public: - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - bsdf->ior = 0.0f; - bsdf->T = zero_float3(); - bsdf->alpha_y = bsdf->alpha_x; - sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf); - } -}; - -ClosureParam *closure_bsdf_microfacet_multi_ggx_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color), - CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"), - CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)}; - return params; -} -CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_prepare, MicrofacetMultiGGXClosure); - -class MicrofacetMultiGGXAnisoClosure : public MicrofacetMultiClosure { - public: - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - bsdf->ior = 0.0f; - sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf); - } -}; - -ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.T), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_y), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color), - CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"), - CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)}; - return params; -} -CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_aniso_prepare, MicrofacetMultiGGXAnisoClosure); - -class MicrofacetMultiGGXGlassClosure : public MicrofacetMultiClosure { - public: - MicrofacetMultiGGXGlassClosure() : MicrofacetMultiClosure() - { - } - - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - bsdf->T = zero_float3(); - bsdf->alpha_y = bsdf->alpha_x; - sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf); - } -}; - -ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.ior), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color), - CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"), - CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)}; - return params; -} -CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_glass_prepare, MicrofacetMultiGGXGlassClosure); - -/* Multiscattering GGX closures with Fresnel */ - -class MicrofacetMultiFresnelClosure : public CBSDFClosure { - public: - MicrofacetBsdf params; - float3 color; - float3 cspec0; - - MicrofacetBsdf *alloc(ShaderData *sd, uint32_t path_flag, float3 weight) - { - /* Technically, the MultiGGX closure may also transmit. However, - * since this is set statically and only used for caustic flags, this - * is probably as good as it gets. */ - if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { - return NULL; - } - - MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), ¶ms); - if (!bsdf) { - return NULL; - } - - MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); - if (!extra) { - return NULL; - } - - bsdf->extra = extra; - bsdf->extra->color = rgb_to_spectrum(color); - bsdf->extra->cspec0 = rgb_to_spectrum(cspec0); - bsdf->extra->clearcoat = 0.0f; - return bsdf; - } -}; - -class MicrofacetMultiGGXFresnelClosure : public MicrofacetMultiFresnelClosure { - public: - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - bsdf->T = zero_float3(); - bsdf->alpha_y = bsdf->alpha_x; - sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd); +#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \ + static OSL::ClosureParam *osl_closure_##lower##_params() \ + { \ + static OSL::ClosureParam params[] = { +#define OSL_CLOSURE_STRUCT_END(Upper, lower) \ + CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), CLOSURE_FINISH_PARAM(Upper##Closure) \ + } \ + ; \ + return params; \ } -}; - -ClosureParam *closure_bsdf_microfacet_multi_ggx_fresnel_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0), - CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"), - CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)}; - return params; -} -CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_fresnel_prepare, - MicrofacetMultiGGXFresnelClosure); +#define OSL_CLOSURE_STRUCT_MEMBER(Upper, TYPE, type, name, key) \ + CLOSURE_##TYPE##_KEYPARAM(Upper##Closure, name, key), +#define OSL_CLOSURE_STRUCT_ARRAY_MEMBER(Upper, TYPE, type, name, key, size) \ + CLOSURE_##TYPE##_ARRAY_PARAM(Upper##Closure, name, size), -class MicrofacetMultiGGXAnisoFresnelClosure : public MicrofacetMultiFresnelClosure { - public: - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); +#include "closures_template.h" - MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd); - } -}; - -ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params() +void OSLRenderServices::register_closures(OSL::ShadingSystem *ss) { - static ClosureParam params[] = { - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.T), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_y), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0), - CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"), - CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)}; - return params; -} -CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare, - MicrofacetMultiGGXAnisoFresnelClosure); - -class MicrofacetMultiGGXGlassFresnelClosure : public MicrofacetMultiFresnelClosure { - public: - MicrofacetMultiGGXGlassFresnelClosure() : MicrofacetMultiFresnelClosure() - { - } +#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \ + ss->register_closure( \ + #lower, OSL_CLOSURE_##Upper##_ID, osl_closure_##lower##_params(), nullptr, nullptr); - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); - - MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight); - if (!bsdf) { - return; - } - - bsdf->T = zero_float3(); - bsdf->alpha_y = bsdf->alpha_x; - sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd); - } -}; - -ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_fresnel_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x), - CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color), - CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0), - CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"), - CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)}; - return params; +#include "closures_template.h" } -CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare, - MicrofacetMultiGGXGlassFresnelClosure); - -/* Transparent */ - -class TransparentClosure : public CBSDFClosure { - public: - ShaderClosure params; - float3 unused; - - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - bsdf_transparent_setup(sd, rgb_to_spectrum(weight), path_flag); - } -}; - -ClosureParam *closure_bsdf_transparent_params() -{ - static ClosureParam params[] = {CLOSURE_STRING_KEYPARAM(TransparentClosure, label, "label"), - CLOSURE_FINISH_PARAM(TransparentClosure)}; - return params; -} - -CCLOSURE_PREPARE(closure_bsdf_transparent_prepare, TransparentClosure) - -/* Volume */ - -class VolumeAbsorptionClosure : public CBSDFClosure { - public: - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - volume_extinction_setup(sd, rgb_to_spectrum(weight)); - } -}; - -ClosureParam *closure_absorption_params() -{ - static ClosureParam params[] = {CLOSURE_STRING_KEYPARAM(VolumeAbsorptionClosure, label, "label"), - CLOSURE_FINISH_PARAM(VolumeAbsorptionClosure)}; - return params; -} - -CCLOSURE_PREPARE(closure_absorption_prepare, VolumeAbsorptionClosure) - -class VolumeHenyeyGreensteinClosure : public CBSDFClosure { - public: - HenyeyGreensteinVolume params; - - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) - { - volume_extinction_setup(sd, rgb_to_spectrum(weight)); - - HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume *)bsdf_alloc_osl( - sd, sizeof(HenyeyGreensteinVolume), rgb_to_spectrum(weight), ¶ms); - if (!volume) { - return; - } - - sd->flag |= volume_henyey_greenstein_setup(volume); - } -}; - -ClosureParam *closure_henyey_greenstein_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT_PARAM(VolumeHenyeyGreensteinClosure, params.g), - CLOSURE_STRING_KEYPARAM(VolumeHenyeyGreensteinClosure, label, "label"), - CLOSURE_FINISH_PARAM(VolumeHenyeyGreensteinClosure)}; - return params; -} - -CCLOSURE_PREPARE(closure_henyey_greenstein_prepare, VolumeHenyeyGreensteinClosure) CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/closures.h b/intern/cycles/kernel/osl/closures.h deleted file mode 100644 index 97666be7a1e..00000000000 --- a/intern/cycles/kernel/osl/closures.h +++ /dev/null @@ -1,142 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Adapted from Open Shading Language - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011-2022 Blender Foundation. */ - -#ifndef __OSL_CLOSURES_H__ -#define __OSL_CLOSURES_H__ - -#include "kernel/types.h" -#include "util/types.h" - -#include <OSL/genclosure.h> -#include <OSL/oslclosure.h> -#include <OSL/oslexec.h> - -CCL_NAMESPACE_BEGIN - -OSL::ClosureParam *closure_emission_params(); -OSL::ClosureParam *closure_background_params(); -OSL::ClosureParam *closure_holdout_params(); -OSL::ClosureParam *closure_bsdf_diffuse_ramp_params(); -OSL::ClosureParam *closure_bsdf_phong_ramp_params(); -OSL::ClosureParam *closure_bsdf_transparent_params(); -OSL::ClosureParam *closure_bssrdf_params(); -OSL::ClosureParam *closure_absorption_params(); -OSL::ClosureParam *closure_henyey_greenstein_params(); -OSL::ClosureParam *closure_bsdf_microfacet_params(); -OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_params(); -OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_params(); -OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_params(); -OSL::ClosureParam *closure_bsdf_microfacet_ggx_fresnel_params(); -OSL::ClosureParam *closure_bsdf_microfacet_ggx_aniso_fresnel_params(); -OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_fresnel_params(); -OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_fresnel_params(); -OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params(); -OSL::ClosureParam *closure_bsdf_principled_clearcoat_params(); - -void closure_emission_prepare(OSL::RendererServices *, int id, void *data); -void closure_background_prepare(OSL::RendererServices *, int id, void *data); -void closure_holdout_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_diffuse_ramp_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_phong_ramp_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_transparent_prepare(OSL::RendererServices *, int id, void *data); -void closure_bssrdf_prepare(OSL::RendererServices *, int id, void *data); -void closure_absorption_prepare(OSL::RendererServices *, int id, void *data); -void closure_henyey_greenstein_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_microfacet_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_microfacet_multi_ggx_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_microfacet_multi_ggx_glass_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_microfacet_multi_ggx_aniso_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_microfacet_ggx_fresnel_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_microfacet_ggx_aniso_fresnel_prepare(OSL::RendererServices *, - int id, - void *data); -void closure_bsdf_microfacet_multi_ggx_fresnel_prepare(OSL::RendererServices *, - int id, - void *data); -void closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare(OSL::RendererServices *, - int id, - void *data); -void closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare(OSL::RendererServices *, - int id, - void *data); -void closure_bsdf_principled_clearcoat_prepare(OSL::RendererServices *, int id, void *data); -void closure_bsdf_principled_hair_prepare(OSL::RendererServices *, int id, void *data); - -#define CCLOSURE_PREPARE(name, classname) \ - void name(RendererServices *, int id, void *data) \ - { \ - memset(data, 0, sizeof(classname)); \ - new (data) classname(); \ - } - -#define CCLOSURE_PREPARE_STATIC(name, classname) static CCLOSURE_PREPARE(name, classname) - -#define CLOSURE_FLOAT3_PARAM(st, fld) \ - { \ - TypeDesc::TypeVector, (int)reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) \ - } - -#define BSDF_CLOSURE_FLOAT_PARAM(st, fld) CLOSURE_FLOAT_PARAM(st, fld), -#define BSDF_CLOSURE_FLOAT3_PARAM(st, fld) CLOSURE_FLOAT3_PARAM(st, fld), - -#define TO_VEC3(v) OSL::Vec3(v.x, v.y, v.z) -#define TO_COLOR3(v) OSL::Color3(v.x, v.y, v.z) -#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2]) - -/* Closure */ - -class CClosurePrimitive { - public: - virtual void setup(ShaderData *sd, uint32_t path_flag, float3 weight) = 0; - - OSL::ustring label; -}; - -/* BSDF */ - -class CBSDFClosure : public CClosurePrimitive { - public: - bool skip(const ShaderData *sd, uint32_t path_flag, int scattering); -}; - -#define BSDF_CLOSURE_CLASS_BEGIN(Upper, lower, structname, TYPE) \ -\ - class Upper##Closure : public CBSDFClosure { \ - public: \ - structname params; \ - float3 unused; \ -\ - void setup(ShaderData *sd, uint32_t path_flag, float3 weight) \ - { \ - if (!skip(sd, path_flag, TYPE)) { \ - params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); \ - structname *bsdf = (structname *)bsdf_alloc_osl( \ - sd, sizeof(structname), rgb_to_spectrum(weight), ¶ms); \ - sd->flag |= (bsdf) ? bsdf_##lower##_setup(bsdf) : 0; \ - } \ - } \ - }; \ -\ - static ClosureParam *bsdf_##lower##_params() \ - { \ - static ClosureParam params[] = { - -/* parameters */ - -#define BSDF_CLOSURE_CLASS_END(Upper, lower) \ - CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), CLOSURE_FINISH_PARAM(Upper##Closure) \ - } \ - ; \ - return params; \ - } \ -\ - CCLOSURE_PREPARE_STATIC(bsdf_##lower##_prepare, Upper##Closure) - -CCL_NAMESPACE_END - -#endif /* __OSL_CLOSURES_H__ */ diff --git a/intern/cycles/kernel/osl/closures_setup.h b/intern/cycles/kernel/osl/closures_setup.h new file mode 100644 index 00000000000..7972bba7d5c --- /dev/null +++ b/intern/cycles/kernel/osl/closures_setup.h @@ -0,0 +1,1166 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Adapted from Open Shading Language + * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. + * All Rights Reserved. + * + * Modifications Copyright 2011-2022 Blender Foundation. */ + +#pragma once + +// clang-format off +#include "kernel/closure/alloc.h" +#include "kernel/closure/bsdf_util.h" +#include "kernel/closure/bsdf_ashikhmin_velvet.h" +#include "kernel/closure/bsdf_diffuse.h" +#include "kernel/closure/bsdf_microfacet.h" +#include "kernel/closure/bsdf_microfacet_multi.h" +#include "kernel/closure/bsdf_oren_nayar.h" +#include "kernel/closure/bsdf_reflection.h" +#include "kernel/closure/bsdf_refraction.h" +#include "kernel/closure/bsdf_transparent.h" +#include "kernel/closure/bsdf_ashikhmin_shirley.h" +#include "kernel/closure/bsdf_toon.h" +#include "kernel/closure/bsdf_hair.h" +#include "kernel/closure/bsdf_hair_principled.h" +#include "kernel/closure/bsdf_principled_diffuse.h" +#include "kernel/closure/bsdf_principled_sheen.h" +#include "kernel/closure/volume.h" +#include "kernel/closure/bsdf_diffuse_ramp.h" +#include "kernel/closure/bsdf_phong_ramp.h" +#include "kernel/closure/bssrdf.h" +#include "kernel/closure/emissive.h" +// clang-format on + +CCL_NAMESPACE_BEGIN + +#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \ + struct ccl_align(8) Upper##Closure \ + { \ + const char *label; +#define OSL_CLOSURE_STRUCT_END(Upper, lower) \ + } \ + ; \ + ccl_device void osl_closure_##lower##_setup(KernelGlobals kg, \ + ccl_private ShaderData *sd, \ + uint32_t path_flag, \ + float3 weight, \ + ccl_private Upper##Closure *closure); +#define OSL_CLOSURE_STRUCT_MEMBER(Upper, TYPE, type, name, key) type name; +#define OSL_CLOSURE_STRUCT_ARRAY_MEMBER(Upper, TYPE, type, name, key, size) type name[size]; + +#include "closures_template.h" + +ccl_device_forceinline bool osl_closure_skip(KernelGlobals kg, + ccl_private const ShaderData *sd, + uint32_t path_flag, + int scattering) +{ + /* caustic options */ + if ((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) { + if ((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) || + (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) { + return true; + } + } + + return false; +} + +/* Diffuse */ + +ccl_device void osl_closure_diffuse_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const DiffuseClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) { + return; + } + + ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc( + sd, sizeof(DiffuseBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + + sd->flag |= bsdf_diffuse_setup(bsdf); +} + +ccl_device void osl_closure_oren_nayar_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const OrenNayarClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) { + return; + } + + ccl_private OrenNayarBsdf *bsdf = (ccl_private OrenNayarBsdf *)bsdf_alloc( + sd, sizeof(OrenNayarBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->roughness = closure->roughness; + + sd->flag |= bsdf_oren_nayar_setup(bsdf); +} + +ccl_device void osl_closure_translucent_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const TranslucentClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) { + return; + } + + ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc( + sd, sizeof(DiffuseBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + + sd->flag |= bsdf_translucent_setup(bsdf); +} + +ccl_device void osl_closure_reflection_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const ReflectionClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_SINGULAR)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + + sd->flag |= bsdf_reflection_setup(bsdf); +} + +ccl_device void osl_closure_refraction_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const RefractionClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_SINGULAR)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->ior = closure->ior; + + sd->flag |= bsdf_refraction_setup(bsdf); +} + +ccl_device void osl_closure_transparent_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const TransparentClosure *closure) +{ + bsdf_transparent_setup(sd, rgb_to_spectrum(weight), path_flag); +} + +/* Standard microfacet closures */ + +ccl_device void osl_closure_microfacet_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetClosure *closure) +{ + const int label = (closure->refract) ? LABEL_TRANSMIT : LABEL_REFLECT; + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | label)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = closure->alpha_y; + bsdf->ior = closure->ior; + bsdf->T = closure->T; + + static OSL::ustring u_ggx("ggx"); + static OSL::ustring u_default("default"); + + /* GGX */ + if (closure->distribution == u_ggx || closure->distribution == u_default) { + if (!closure->refract) { + if (closure->alpha_x == closure->alpha_y) { + /* Isotropic */ + sd->flag |= bsdf_microfacet_ggx_isotropic_setup(bsdf); + } + else { + /* Anisotropic */ + sd->flag |= bsdf_microfacet_ggx_setup(bsdf); + } + } + else { + sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); + } + } + /* Beckmann */ + else { + if (!closure->refract) { + if (closure->alpha_x == closure->alpha_y) { + /* Isotropic */ + sd->flag |= bsdf_microfacet_beckmann_isotropic_setup(bsdf); + } + else { + /* Anisotropic */ + sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); + } + } + else { + sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf); + } + } +} + +ccl_device void osl_closure_microfacet_ggx_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetGGXIsotropicClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + + sd->flag |= bsdf_microfacet_ggx_isotropic_setup(bsdf); +} + +ccl_device void osl_closure_microfacet_ggx_aniso_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetGGXClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = closure->alpha_y; + bsdf->T = closure->T; + + sd->flag |= bsdf_microfacet_ggx_setup(bsdf); +} + +ccl_device void osl_closure_microfacet_ggx_refraction_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetGGXRefractionClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_TRANSMIT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->ior = closure->ior; + + sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); +} + +/* GGX closures with Fresnel */ + +ccl_device void osl_closure_microfacet_ggx_fresnel_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetGGXFresnelClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + ccl_private MicrofacetExtra *extra = (ccl_private MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = bsdf->alpha_x; + bsdf->ior = closure->ior; + + bsdf->extra = extra; + bsdf->extra->color = rgb_to_spectrum(closure->color); + bsdf->extra->cspec0 = rgb_to_spectrum(closure->cspec0); + bsdf->extra->clearcoat = 0.0f; + + bsdf->T = zero_float3(); + + sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd); +} + +ccl_device void osl_closure_microfacet_ggx_aniso_fresnel_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetGGXAnisoFresnelClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + ccl_private MicrofacetExtra *extra = (ccl_private MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = closure->alpha_y; + bsdf->ior = closure->ior; + + bsdf->extra = extra; + bsdf->extra->color = rgb_to_spectrum(closure->color); + bsdf->extra->cspec0 = rgb_to_spectrum(closure->cspec0); + bsdf->extra->clearcoat = 0.0f; + + bsdf->T = closure->T; + + sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd); +} + +/* Multiscattering GGX closures */ + +ccl_device void osl_closure_microfacet_multi_ggx_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetMultiGGXClosure *closure) +{ + /* Technically, the MultiGGX closure may also transmit. However, + * since this is set statically and only used for caustic flags, this + * is probably as good as it gets. */ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + ccl_private MicrofacetExtra *extra = (ccl_private MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = bsdf->alpha_x; + bsdf->ior = 0.0f; + + bsdf->extra = extra; + bsdf->extra->color = rgb_to_spectrum(closure->color); + bsdf->extra->cspec0 = zero_spectrum(); + bsdf->extra->clearcoat = 0.0f; + + bsdf->T = zero_float3(); + + sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf); +} + +ccl_device void osl_closure_microfacet_multi_ggx_glass_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetMultiGGXGlassClosure *closure) +{ + /* Technically, the MultiGGX closure may also transmit. However, + * since this is set statically and only used for caustic flags, this + * is probably as good as it gets. */ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + ccl_private MicrofacetExtra *extra = (ccl_private MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = bsdf->alpha_x; + bsdf->ior = closure->ior; + + bsdf->extra = extra; + bsdf->extra->color = rgb_to_spectrum(closure->color); + bsdf->extra->cspec0 = zero_spectrum(); + bsdf->extra->clearcoat = 0.0f; + + bsdf->T = zero_float3(); + + sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf); +} + +ccl_device void osl_closure_microfacet_multi_ggx_aniso_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetMultiGGXAnisoClosure *closure) +{ + /* Technically, the MultiGGX closure may also transmit. However, + * since this is set statically and only used for caustic flags, this + * is probably as good as it gets. */ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + ccl_private MicrofacetExtra *extra = (ccl_private MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = closure->alpha_y; + bsdf->ior = 0.0f; + + bsdf->extra = extra; + bsdf->extra->color = rgb_to_spectrum(closure->color); + bsdf->extra->cspec0 = zero_spectrum(); + bsdf->extra->clearcoat = 0.0f; + + bsdf->T = closure->T; + + sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf); +} + +/* Multiscattering GGX closures with Fresnel */ + +ccl_device void osl_closure_microfacet_multi_ggx_fresnel_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetMultiGGXFresnelClosure *closure) +{ + /* Technically, the MultiGGX closure may also transmit. However, + * since this is set statically and only used for caustic flags, this + * is probably as good as it gets. */ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + ccl_private MicrofacetExtra *extra = (ccl_private MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = bsdf->alpha_x; + bsdf->ior = closure->ior; + + bsdf->extra = extra; + bsdf->extra->color = rgb_to_spectrum(closure->color); + bsdf->extra->cspec0 = rgb_to_spectrum(closure->cspec0); + bsdf->extra->clearcoat = 0.0f; + + bsdf->T = zero_float3(); + + sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd); +} + +ccl_device void osl_closure_microfacet_multi_ggx_glass_fresnel_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetMultiGGXGlassFresnelClosure *closure) +{ + /* Technically, the MultiGGX closure may also transmit. However, + * since this is set statically and only used for caustic flags, this + * is probably as good as it gets. */ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + ccl_private MicrofacetExtra *extra = (ccl_private MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = bsdf->alpha_x; + bsdf->ior = closure->ior; + + bsdf->extra = extra; + bsdf->extra->color = rgb_to_spectrum(closure->color); + bsdf->extra->cspec0 = rgb_to_spectrum(closure->cspec0); + bsdf->extra->clearcoat = 0.0f; + + bsdf->T = zero_float3(); + + sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd); +} + +ccl_device void osl_closure_microfacet_multi_ggx_aniso_fresnel_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetMultiGGXAnisoFresnelClosure *closure) +{ + /* Technically, the MultiGGX closure may also transmit. However, + * since this is set statically and only used for caustic flags, this + * is probably as good as it gets. */ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + ccl_private MicrofacetExtra *extra = (ccl_private MicrofacetExtra *)closure_alloc_extra( + sd, sizeof(MicrofacetExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = closure->alpha_y; + bsdf->ior = closure->ior; + + bsdf->extra = extra; + bsdf->extra->color = rgb_to_spectrum(closure->color); + bsdf->extra->cspec0 = rgb_to_spectrum(closure->cspec0); + bsdf->extra->clearcoat = 0.0f; + + bsdf->T = closure->T; + + sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd); +} + +/* Beckmann closures */ + +ccl_device void osl_closure_microfacet_beckmann_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetBeckmannIsotropicClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + + sd->flag |= bsdf_microfacet_beckmann_isotropic_setup(bsdf); +} + +ccl_device void osl_closure_microfacet_beckmann_aniso_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetBeckmannClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = closure->alpha_y; + bsdf->T = closure->T; + + sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); +} + +ccl_device void osl_closure_microfacet_beckmann_refraction_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const MicrofacetBeckmannRefractionClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_TRANSMIT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->ior = closure->ior; + + sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf); +} + +/* Ashikhmin closures */ + +ccl_device void osl_closure_ashikhmin_velvet_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const AshikhminVelvetClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) { + return; + } + + ccl_private VelvetBsdf *bsdf = (ccl_private VelvetBsdf *)bsdf_alloc( + sd, sizeof(VelvetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->sigma = closure->sigma; + + sd->flag |= bsdf_ashikhmin_velvet_setup(bsdf); +} + +ccl_device void osl_closure_ashikhmin_shirley_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const AshikhminShirleyClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { + return; + } + + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->alpha_x; + bsdf->alpha_y = closure->alpha_y; + bsdf->T = closure->T; + + sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf); +} + +ccl_device void osl_closure_diffuse_toon_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const DiffuseToonClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) { + return; + } + + ccl_private ToonBsdf *bsdf = (ccl_private ToonBsdf *)bsdf_alloc( + sd, sizeof(ToonBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->size = closure->size; + bsdf->smooth = closure->smooth; + + sd->flag |= bsdf_diffuse_toon_setup(bsdf); +} + +ccl_device void osl_closure_glossy_toon_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const GlossyToonClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY)) { + return; + } + + ccl_private ToonBsdf *bsdf = (ccl_private ToonBsdf *)bsdf_alloc( + sd, sizeof(ToonBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->size = closure->size; + bsdf->smooth = closure->smooth; + + sd->flag |= bsdf_glossy_toon_setup(bsdf); +} + +/* Disney principled closures */ + +ccl_device void osl_closure_principled_diffuse_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const PrincipledDiffuseClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) { + return; + } + + ccl_private PrincipledDiffuseBsdf *bsdf = (ccl_private PrincipledDiffuseBsdf *)bsdf_alloc( + sd, sizeof(PrincipledDiffuseBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->roughness = closure->roughness; + + sd->flag |= bsdf_principled_diffuse_setup(bsdf); +} + +ccl_device void osl_closure_principled_sheen_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const PrincipledSheenClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_DIFFUSE)) { + return; + } + + ccl_private PrincipledSheenBsdf *bsdf = (ccl_private PrincipledSheenBsdf *)bsdf_alloc( + sd, sizeof(PrincipledSheenBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->avg_value = 0.0f; + + sd->flag |= bsdf_principled_sheen_setup(sd, bsdf); +} + +ccl_device void osl_closure_principled_clearcoat_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const PrincipledClearcoatClosure *closure) +{ + ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->alpha_x = closure->clearcoat_roughness; + bsdf->alpha_y = closure->clearcoat_roughness; + bsdf->ior = 1.5f; + + bsdf->extra = extra; + bsdf->extra->color = zero_spectrum(); + bsdf->extra->cspec0 = make_spectrum(0.04f); + bsdf->extra->clearcoat = closure->clearcoat; + + bsdf->T = zero_float3(); + + sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd); +} + +/* Variable cone emissive closure + * + * This primitive emits in a cone having a configurable penumbra area where the light decays to 0 + * reaching the outer_angle limit. It can also behave as a lambertian emitter if the provided + * angles are PI/2, which is the default + */ +ccl_device void osl_closure_emission_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t /* path_flag */, + float3 weight, + ccl_private const GenericEmissiveClosure *closure) +{ + emission_setup(sd, rgb_to_spectrum(weight)); +} + +/* Generic background closure + * + * We only have a background closure for the shaders to return a color in background shaders. No + * methods, only the weight is taking into account + */ +ccl_device void osl_closure_background_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t /* path_flag */, + float3 weight, + ccl_private const GenericBackgroundClosure *closure) +{ + background_setup(sd, rgb_to_spectrum(weight)); +} + +/* Holdout closure + * + * This will be used by the shader to mark the amount of holdout for the current shading point. No + * parameters, only the weight will be used + */ +ccl_device void osl_closure_holdout_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t /* path_flag */, + float3 weight, + ccl_private const HoldoutClosure *closure) +{ + closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, rgb_to_spectrum(weight)); + sd->flag |= SD_HOLDOUT; +} + +ccl_device void osl_closure_diffuse_ramp_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t /* path_flag */, + float3 weight, + ccl_private const DiffuseRampClosure *closure) +{ + ccl_private DiffuseRampBsdf *bsdf = (ccl_private DiffuseRampBsdf *)bsdf_alloc( + sd, sizeof(DiffuseRampBsdf), rgb_to_spectrum(weight)); + + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + + bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8); + if (!bsdf->colors) { + return; + } + + for (int i = 0; i < 8; i++) + bsdf->colors[i] = closure->colors[i]; + + sd->flag |= bsdf_diffuse_ramp_setup(bsdf); +} + +ccl_device void osl_closure_phong_ramp_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t /* path_flag */, + float3 weight, + ccl_private const PhongRampClosure *closure) +{ + ccl_private PhongRampBsdf *bsdf = (ccl_private PhongRampBsdf *)bsdf_alloc( + sd, sizeof(PhongRampBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->exponent = closure->exponent; + + bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8); + if (!bsdf->colors) { + return; + } + + for (int i = 0; i < 8; i++) + bsdf->colors[i] = closure->colors[i]; + + sd->flag |= bsdf_phong_ramp_setup(bsdf); +} + +ccl_device void osl_closure_bssrdf_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const BSSRDFClosure *closure) +{ + static ustring u_burley("burley"); + static ustring u_random_walk_fixed_radius("random_walk_fixed_radius"); + static ustring u_random_walk("random_walk"); + + ClosureType type; + if (closure->method == u_burley) { + type = CLOSURE_BSSRDF_BURLEY_ID; + } + else if (closure->method == u_random_walk_fixed_radius) { + type = CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID; + } + else if (closure->method == u_random_walk) { + type = CLOSURE_BSSRDF_RANDOM_WALK_ID; + } + else { + return; + } + + ccl_private Bssrdf *bssrdf = bssrdf_alloc(sd, rgb_to_spectrum(weight)); + if (!bssrdf) { + return; + } + + /* disable in case of diffuse ancestor, can't see it well then and + * adds considerably noise due to probabilities of continuing path + * getting lower and lower */ + if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR) { + bssrdf->radius = zero_spectrum(); + } + else { + bssrdf->radius = closure->radius; + } + + /* create one closure per color channel */ + bssrdf->albedo = closure->albedo; + bssrdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bssrdf->roughness = closure->roughness; + bssrdf->anisotropy = clamp(closure->anisotropy, 0.0f, 0.9f); + + sd->flag |= bssrdf_setup(sd, bssrdf, type, clamp(closure->ior, 1.01f, 3.8f)); +} + +/* Hair */ + +ccl_device void osl_closure_hair_reflection_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const HairReflectionClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY)) { + return; + } + + ccl_private HairBsdf *bsdf = (ccl_private HairBsdf *)bsdf_alloc( + sd, sizeof(HairBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->T = closure->T; + bsdf->roughness1 = closure->roughness1; + bsdf->roughness2 = closure->roughness2; + bsdf->offset = closure->offset; + + sd->flag |= bsdf_hair_reflection_setup(bsdf); +} + +ccl_device void osl_closure_hair_transmission_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const HairTransmissionClosure *closure) +{ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY)) { + return; + } + + ccl_private HairBsdf *bsdf = (ccl_private HairBsdf *)bsdf_alloc( + sd, sizeof(HairBsdf), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->T = closure->T; + bsdf->roughness1 = closure->roughness1; + bsdf->roughness2 = closure->roughness2; + bsdf->offset = closure->offset; + + sd->flag |= bsdf_hair_transmission_setup(bsdf); +} + +ccl_device void osl_closure_principled_hair_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const PrincipledHairClosure *closure) +{ +#ifdef __HAIR__ + if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY)) { + return; + } + + ccl_private PrincipledHairBSDF *bsdf = (ccl_private PrincipledHairBSDF *)bsdf_alloc( + sd, sizeof(PrincipledHairBSDF), rgb_to_spectrum(weight)); + if (!bsdf) { + return; + } + + ccl_private PrincipledHairExtra *extra = (ccl_private PrincipledHairExtra *)closure_alloc_extra( + sd, sizeof(PrincipledHairExtra)); + if (!extra) { + return; + } + + bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->sigma = closure->sigma; + bsdf->v = closure->v; + bsdf->s = closure->s; + bsdf->alpha = closure->alpha; + bsdf->eta = closure->eta; + bsdf->m0_roughness = closure->m0_roughness; + + bsdf->extra = extra; + + sd->flag |= bsdf_principled_hair_setup(sd, bsdf); +#endif +} + +/* Volume */ + +ccl_device void osl_closure_absorption_setup(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const VolumeAbsorptionClosure *closure) +{ + volume_extinction_setup(sd, rgb_to_spectrum(weight)); +} + +ccl_device void osl_closure_henyey_greenstein_setup( + KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + float3 weight, + ccl_private const VolumeHenyeyGreensteinClosure *closure) +{ + volume_extinction_setup(sd, rgb_to_spectrum(weight)); + + ccl_private HenyeyGreensteinVolume *volume = (ccl_private HenyeyGreensteinVolume *)bsdf_alloc( + sd, sizeof(HenyeyGreensteinVolume), rgb_to_spectrum(weight)); + if (!volume) { + return; + } + + volume->g = closure->g; + + sd->flag |= volume_henyey_greenstein_setup(volume); +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/closures_template.h b/intern/cycles/kernel/osl/closures_template.h new file mode 100644 index 00000000000..c808b275966 --- /dev/null +++ b/intern/cycles/kernel/osl/closures_template.h @@ -0,0 +1,258 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#ifndef OSL_CLOSURE_STRUCT_BEGIN +# define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) +#endif +#ifndef OSL_CLOSURE_STRUCT_END +# define OSL_CLOSURE_STRUCT_END(Upper, lower) +#endif +#ifndef OSL_CLOSURE_STRUCT_MEMBER +# define OSL_CLOSURE_STRUCT_MEMBER(Upper, TYPE, type, name, key) +#endif +#ifndef OSL_CLOSURE_STRUCT_ARRAY_MEMBER +# define OSL_CLOSURE_STRUCT_ARRAY_MEMBER(Upper, TYPE, type, name, key, size) +#endif + +OSL_CLOSURE_STRUCT_BEGIN(Diffuse, diffuse) + OSL_CLOSURE_STRUCT_MEMBER(Diffuse, VECTOR, packed_float3, N, NULL) +OSL_CLOSURE_STRUCT_END(Diffuse, diffuse) + +OSL_CLOSURE_STRUCT_BEGIN(OrenNayar, oren_nayar) + OSL_CLOSURE_STRUCT_MEMBER(OrenNayar, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(OrenNayar, FLOAT, float, roughness, NULL) +OSL_CLOSURE_STRUCT_END(OrenNayar, oren_nayar) + +OSL_CLOSURE_STRUCT_BEGIN(Translucent, translucent) + OSL_CLOSURE_STRUCT_MEMBER(Translucent, VECTOR, packed_float3, N, NULL) +OSL_CLOSURE_STRUCT_END(Translucent, translucent) + +OSL_CLOSURE_STRUCT_BEGIN(Reflection, reflection) + OSL_CLOSURE_STRUCT_MEMBER(Reflection, VECTOR, packed_float3, N, NULL) +OSL_CLOSURE_STRUCT_END(Reflection, reflection) + +OSL_CLOSURE_STRUCT_BEGIN(Refraction, refraction) + OSL_CLOSURE_STRUCT_MEMBER(Refraction, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(Refraction, FLOAT, float, ior, NULL) +OSL_CLOSURE_STRUCT_END(Refraction, refraction) + +OSL_CLOSURE_STRUCT_BEGIN(Transparent, transparent) +OSL_CLOSURE_STRUCT_END(Transparent, transparent) + +OSL_CLOSURE_STRUCT_BEGIN(Microfacet, microfacet) + OSL_CLOSURE_STRUCT_MEMBER(Microfacet, STRING, ustring, distribution, NULL) + OSL_CLOSURE_STRUCT_MEMBER(Microfacet, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(Microfacet, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(Microfacet, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(Microfacet, FLOAT, float, alpha_y, NULL) + OSL_CLOSURE_STRUCT_MEMBER(Microfacet, FLOAT, float, ior, NULL) + OSL_CLOSURE_STRUCT_MEMBER(Microfacet, INT, int, refract, NULL) +OSL_CLOSURE_STRUCT_END(Microfacet, microfacet) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXIsotropic, microfacet_ggx) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXIsotropic, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXIsotropic, FLOAT, float, alpha_x, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetGGXIsotropic, microfacet_ggx) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGX, microfacet_ggx_aniso) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, FLOAT, float, alpha_y, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetGGX, microfacet_ggx_aniso) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXRefraction, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXRefraction, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXRefraction, FLOAT, float, ior, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetGGXRefraction, microfacet_ggx_refraction) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGX, microfacet_multi_ggx) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, VECTOR, packed_float3, color, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGX, microfacet_multi_ggx) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXGlass, microfacet_multi_ggx_glass) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, FLOAT, float, ior, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, VECTOR, packed_float3, color, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXGlass, microfacet_multi_ggx_glass) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXAniso, microfacet_multi_ggx_aniso) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, FLOAT, float, alpha_y, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, VECTOR, packed_float3, color, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXAniso, microfacet_multi_ggx_aniso) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXFresnel, microfacet_ggx_fresnel) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, FLOAT, float, ior, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, VECTOR, packed_float3, color, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, VECTOR, packed_float3, cspec0, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetGGXFresnel, microfacet_ggx_fresnel) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXAnisoFresnel, microfacet_ggx_aniso_fresnel) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, FLOAT, float, alpha_y, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, FLOAT, float, ior, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, color, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, cspec0, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetGGXAnisoFresnel, microfacet_ggx_aniso_fresnel) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXFresnel, microfacet_multi_ggx_fresnel) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, FLOAT, float, ior, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, VECTOR, packed_float3, color, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, VECTOR, packed_float3, cspec0, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXFresnel, microfacet_multi_ggx_fresnel) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXGlassFresnel, microfacet_multi_ggx_glass_fresnel) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, FLOAT, float, ior, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, VECTOR, packed_float3, color, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, VECTOR, packed_float3, cspec0, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXGlassFresnel, microfacet_multi_ggx_glass_fresnel) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXAnisoFresnel, microfacet_multi_ggx_aniso_fresnel) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, FLOAT, float, alpha_y, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, FLOAT, float, ior, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, color, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, cspec0, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXAnisoFresnel, microfacet_multi_ggx_aniso_fresnel) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetBeckmannIsotropic, microfacet_beckmann) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannIsotropic, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannIsotropic, FLOAT, float, alpha_x, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetBeckmannIsotropic, microfacet_beckmann) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetBeckmann, microfacet_beckmann_aniso) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, FLOAT, float, alpha_y, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetBeckmann, microfacet_beckmann_aniso) + +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannRefraction, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannRefraction, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannRefraction, FLOAT, float, ior, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction) + +OSL_CLOSURE_STRUCT_BEGIN(AshikhminShirley, ashikhmin_shirley) + OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, FLOAT, float, alpha_y, NULL) +OSL_CLOSURE_STRUCT_END(AshikhminShirley, ashikhmin_shirley) + +OSL_CLOSURE_STRUCT_BEGIN(AshikhminVelvet, ashikhmin_velvet) + OSL_CLOSURE_STRUCT_MEMBER(AshikhminVelvet, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(AshikhminVelvet, FLOAT, float, sigma, NULL) +OSL_CLOSURE_STRUCT_END(AshikhminVelvet, ashikhmin_velvet) + +OSL_CLOSURE_STRUCT_BEGIN(DiffuseToon, diffuse_toon) + OSL_CLOSURE_STRUCT_MEMBER(DiffuseToon, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(DiffuseToon, FLOAT, float, size, NULL) + OSL_CLOSURE_STRUCT_MEMBER(DiffuseToon, FLOAT, float, smooth, NULL) +OSL_CLOSURE_STRUCT_END(DiffuseToon, diffuse_toon) + +OSL_CLOSURE_STRUCT_BEGIN(GlossyToon, glossy_toon) + OSL_CLOSURE_STRUCT_MEMBER(GlossyToon, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(GlossyToon, FLOAT, float, size, NULL) + OSL_CLOSURE_STRUCT_MEMBER(GlossyToon, FLOAT, float, smooth, NULL) +OSL_CLOSURE_STRUCT_END(GlossyToon, glossy_toon) + +OSL_CLOSURE_STRUCT_BEGIN(PrincipledDiffuse, principled_diffuse) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledDiffuse, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledDiffuse, FLOAT, float, roughness, NULL) +OSL_CLOSURE_STRUCT_END(PrincipledDiffuse, principled_diffuse) + +OSL_CLOSURE_STRUCT_BEGIN(PrincipledSheen, principled_sheen) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledSheen, VECTOR, packed_float3, N, NULL) +OSL_CLOSURE_STRUCT_END(PrincipledSheen, principled_sheen) + +OSL_CLOSURE_STRUCT_BEGIN(PrincipledClearcoat, principled_clearcoat) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledClearcoat, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledClearcoat, FLOAT, float, clearcoat, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledClearcoat, FLOAT, float, clearcoat_roughness, NULL) +OSL_CLOSURE_STRUCT_END(PrincipledClearcoat, principled_clearcoat) + +OSL_CLOSURE_STRUCT_BEGIN(GenericEmissive, emission) +OSL_CLOSURE_STRUCT_END(GenericEmissive, emission) + +OSL_CLOSURE_STRUCT_BEGIN(GenericBackground, background) +OSL_CLOSURE_STRUCT_END(GenericBackground, background) + +OSL_CLOSURE_STRUCT_BEGIN(Holdout, holdout) +OSL_CLOSURE_STRUCT_END(Holdout, holdout) + +OSL_CLOSURE_STRUCT_BEGIN(DiffuseRamp, diffuse_ramp) + OSL_CLOSURE_STRUCT_MEMBER(DiffuseRamp, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_ARRAY_MEMBER(DiffuseRamp, COLOR, packed_float3, colors, NULL, 8) +OSL_CLOSURE_STRUCT_END(DiffuseRamp, diffuse_ramp) + +OSL_CLOSURE_STRUCT_BEGIN(PhongRamp, phong_ramp) + OSL_CLOSURE_STRUCT_MEMBER(PhongRamp, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PhongRamp, FLOAT, float, exponent, NULL) + OSL_CLOSURE_STRUCT_ARRAY_MEMBER(PhongRamp, COLOR, packed_float3, colors, NULL, 8) +OSL_CLOSURE_STRUCT_END(PhongRamp, phong_ramp) + +OSL_CLOSURE_STRUCT_BEGIN(BSSRDF, bssrdf) + OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, STRING, ustring, method, NULL) + OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, VECTOR, packed_float3, radius, NULL) + OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, VECTOR, packed_float3, albedo, NULL) + OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, FLOAT, float, roughness, "roughness") + OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, FLOAT, float, ior, "ior") + OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, FLOAT, float, anisotropy, "anisotropy") +OSL_CLOSURE_STRUCT_END(BSSRDF, bssrdf) + +OSL_CLOSURE_STRUCT_BEGIN(HairReflection, hair_reflection) + OSL_CLOSURE_STRUCT_MEMBER(HairReflection, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(HairReflection, FLOAT, float, roughness1, NULL) + OSL_CLOSURE_STRUCT_MEMBER(HairReflection, FLOAT, float, roughness2, NULL) + OSL_CLOSURE_STRUCT_MEMBER(HairReflection, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(HairReflection, FLOAT, float, offset, NULL) +OSL_CLOSURE_STRUCT_END(HairReflection, hair_reflection) + +OSL_CLOSURE_STRUCT_BEGIN(HairTransmission, hair_transmission) + OSL_CLOSURE_STRUCT_MEMBER(HairTransmission, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(HairTransmission, FLOAT, float, roughness1, NULL) + OSL_CLOSURE_STRUCT_MEMBER(HairTransmission, FLOAT, float, roughness2, NULL) + OSL_CLOSURE_STRUCT_MEMBER(HairReflection, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(HairReflection, FLOAT, float, offset, NULL) +OSL_CLOSURE_STRUCT_END(HairTransmission, hair_transmission) + +OSL_CLOSURE_STRUCT_BEGIN(PrincipledHair, principled_hair) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, VECTOR, packed_float3, sigma, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, v, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, s, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, m0_roughness, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, alpha, NULL) + OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, eta, NULL) +OSL_CLOSURE_STRUCT_END(PrincipledHair, principled_hair) + +OSL_CLOSURE_STRUCT_BEGIN(VolumeAbsorption, absorption) +OSL_CLOSURE_STRUCT_END(VolumeAbsorption, absorption) + +OSL_CLOSURE_STRUCT_BEGIN(VolumeHenyeyGreenstein, henyey_greenstein) + OSL_CLOSURE_STRUCT_MEMBER(VolumeHenyeyGreenstein, FLOAT, float, g, NULL) +OSL_CLOSURE_STRUCT_END(VolumeHenyeyGreenstein, henyey_greenstein) + +#undef OSL_CLOSURE_STRUCT_BEGIN +#undef OSL_CLOSURE_STRUCT_END +#undef OSL_CLOSURE_STRUCT_MEMBER +#undef OSL_CLOSURE_STRUCT_ARRAY_MEMBER diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp deleted file mode 100644 index 8d1928d0126..00000000000 --- a/intern/cycles/kernel/osl/emissive.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Adapted from Open Shading Language - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011-2022 Blender Foundation. */ - -#include <OpenImageIO/fmath.h> - -#include <OSL/genclosure.h> - -#include "kernel/osl/closures.h" - -// clang-format off -#include "kernel/device/cpu/compat.h" -#include "kernel/device/cpu/globals.h" - -#include "kernel/types.h" -#include "kernel/closure/alloc.h" -#include "kernel/closure/emissive.h" - -#include "kernel/util/color.h" -// clang-format on - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -/// Variable cone emissive closure -/// -/// This primitive emits in a cone having a configurable -/// penumbra area where the light decays to 0 reaching the -/// outer_angle limit. It can also behave as a lambertian emitter -/// if the provided angles are PI/2, which is the default -/// -class GenericEmissiveClosure : public CClosurePrimitive { - public: - void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight) - { - emission_setup(sd, rgb_to_spectrum(weight)); - } -}; - -ClosureParam *closure_emission_params() -{ - static ClosureParam params[] = {CLOSURE_STRING_KEYPARAM(GenericEmissiveClosure, label, "label"), - CLOSURE_FINISH_PARAM(GenericEmissiveClosure)}; - return params; -} - -CCLOSURE_PREPARE(closure_emission_prepare, GenericEmissiveClosure) - -CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/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; |