Blender V4.3
closures.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009-2010 Sony Pictures Imageworks Inc., et al. All Rights Reserved.
2 * SPDX-FileCopyrightText: 2011-2022 Blender Foundation
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 * Adapted code from Open Shading Language. */
7
8#include <OSL/genclosure.h>
9#include <OSL/oslclosure.h>
10
11#include "kernel/types.h"
12
13#include "kernel/osl/globals.h"
14#include "kernel/osl/services.h"
15
16#include "util/math.h"
17#include "util/param.h"
18
21
22#include "kernel/geom/object.h"
24
25#include "kernel/osl/osl.h"
26
27#define TO_VEC3(v) OSL::Vec3(v.x, v.y, v.z)
28#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2])
29
31
32static_assert(sizeof(OSLClosure) == sizeof(OSL::ClosureColor) &&
33 sizeof(OSLClosureAdd) == sizeof(OSL::ClosureAdd) &&
34 sizeof(OSLClosureMul) == sizeof(OSL::ClosureMul) &&
35 sizeof(OSLClosureComponent) == sizeof(OSL::ClosureComponent));
36static_assert(sizeof(ShaderGlobals) == sizeof(OSL::ShaderGlobals) &&
37 offsetof(ShaderGlobals, Ci) == offsetof(OSL::ShaderGlobals, Ci));
38
39/* Registration */
40
41#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \
42 static OSL::ClosureParam *osl_closure_##lower##_params() \
43 { \
44 static OSL::ClosureParam params[] = {
45#define OSL_CLOSURE_STRUCT_END(Upper, lower) \
46 CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), CLOSURE_FINISH_PARAM(Upper##Closure) \
47 } \
48 ; \
49 return params; \
50 }
51#define OSL_CLOSURE_STRUCT_MEMBER(Upper, TYPE, type, name, key) \
52 CLOSURE_##TYPE##_KEYPARAM(Upper##Closure, name, key),
53#define OSL_CLOSURE_STRUCT_ARRAY_MEMBER(Upper, TYPE, type, name, key, size) \
54 CLOSURE_##TYPE##_ARRAY_PARAM(Upper##Closure, name, size),
55
56#include "closures_template.h"
57
58static OSL::ClosureParam *osl_closure_layer_params()
59{
60 static OSL::ClosureParam params[] = {CLOSURE_CLOSURE_PARAM(LayerClosure, top),
61 CLOSURE_CLOSURE_PARAM(LayerClosure, base),
62 CLOSURE_FINISH_PARAM(LayerClosure)};
63 return params;
64}
65
66void OSLRenderServices::register_closures(OSL::ShadingSystem *ss)
67{
68#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \
69 ss->register_closure( \
70 #lower, OSL_CLOSURE_##Upper##_ID, osl_closure_##lower##_params(), nullptr, nullptr);
71
72#include "closures_template.h"
73 ss->register_closure(
74 "layer", OSL_CLOSURE_LAYER_ID, osl_closure_layer_params(), nullptr, nullptr);
75}
76
77/* Surface & Background */
78
79template<>
81 const void *state,
82 ShaderData *sd,
83 uint32_t path_flag)
84{
85 /* setup shader globals from shader data */
86 OSLThreadData *tdata = kg->osl_tdata;
88 kg, sd, path_flag, reinterpret_cast<ShaderGlobals *>(&tdata->globals));
89
90 /* clear trace data */
91 tdata->tracedata.init = false;
92
93 /* Used by render-services. */
94 sd->osl_globals = kg;
95 if (path_flag & PATH_RAY_SHADOW) {
96 sd->osl_path_state = nullptr;
97 sd->osl_shadow_path_state = (const IntegratorShadowStateCPU *)state;
98 }
99 else {
100 sd->osl_path_state = (const IntegratorStateCPU *)state;
101 sd->osl_shadow_path_state = nullptr;
102 }
103
104 /* execute shader for this point */
105 OSL::ShadingSystem *ss = (OSL::ShadingSystem *)kg->osl_ss;
106 OSL::ShaderGlobals *globals = &tdata->globals;
107 OSL::ShadingContext *octx = tdata->context;
108 int shader = sd->shader & SHADER_MASK;
109
110 if (sd->object == OBJECT_NONE && sd->lamp == LAMP_NONE) {
111 /* background */
112 if (kg->osl->background_state) {
113#if OSL_LIBRARY_VERSION_CODE >= 11304
114 ss->execute(*octx,
115 *(kg->osl->background_state),
116 kg->osl_thread_index,
117 0,
118 *globals,
119 nullptr,
120 nullptr);
121#else
122 ss->execute(octx, *(kg->osl->background_state), *globals);
123#endif
124 }
125 }
126 else {
127 /* automatic bump shader */
128 if (kg->osl->bump_state[shader]) {
129 /* save state */
130 const float3 P = sd->P;
131 const float dP = sd->dP;
132 const OSL::Vec3 dPdx = globals->dPdx;
133 const OSL::Vec3 dPdy = globals->dPdy;
134
135 /* set state as if undisplaced */
136 if (sd->flag & SD_HAS_DISPLACEMENT) {
137 float data[9];
138 bool found = kg->osl->services->get_attribute(sd,
139 true,
141 TypeDesc::TypeVector,
143 data);
144 (void)found;
145 assert(found);
146
147 differential3 tmp_dP;
148 memcpy(&sd->P, data, sizeof(float) * 3);
149 memcpy(&tmp_dP.dx, data + 3, sizeof(float) * 3);
150 memcpy(&tmp_dP.dy, data + 6, sizeof(float) * 3);
151
152 object_position_transform(kg, sd, &sd->P);
153 object_dir_transform(kg, sd, &tmp_dP.dx);
154 object_dir_transform(kg, sd, &tmp_dP.dy);
155
156 sd->dP = differential_make_compact(tmp_dP);
157
158 globals->P = TO_VEC3(sd->P);
159 globals->dPdx = TO_VEC3(tmp_dP.dx);
160 globals->dPdy = TO_VEC3(tmp_dP.dy);
161 }
162
163/* execute bump shader */
164#if OSL_LIBRARY_VERSION_CODE >= 11304
165 ss->execute(*octx,
166 *(kg->osl->bump_state[shader]),
167 kg->osl_thread_index,
168 0,
169 *globals,
170 nullptr,
171 nullptr);
172#else
173 ss->execute(octx, *(kg->osl->bump_state[shader]), *globals);
174#endif
175
176 /* reset state */
177 sd->P = P;
178 sd->dP = dP;
179
180 globals->P = TO_VEC3(P);
181 globals->dPdx = TO_VEC3(dPdx);
182 globals->dPdy = TO_VEC3(dPdy);
183 }
184
185 /* surface shader */
186 if (kg->osl->surface_state[shader]) {
187#if OSL_LIBRARY_VERSION_CODE >= 11304
188 ss->execute(*octx,
189 *(kg->osl->surface_state[shader]),
190 kg->osl_thread_index,
191 0,
192 *globals,
193 nullptr,
194 nullptr);
195#else
196 ss->execute(octx, *(kg->osl->surface_state[shader]), *globals);
197#endif
198 }
199 }
200
201 /* flatten closure tree */
202 if (globals->Ci) {
203 flatten_closure_tree(kg, sd, path_flag, reinterpret_cast<OSLClosure *>(globals->Ci));
204 }
205}
206
207/* Volume */
208
209template<>
211 const void *state,
212 ShaderData *sd,
213 uint32_t path_flag)
214{
215 /* setup shader globals from shader data */
216 OSLThreadData *tdata = kg->osl_tdata;
218 kg, sd, path_flag, reinterpret_cast<ShaderGlobals *>(&tdata->globals));
219
220 /* clear trace data */
221 tdata->tracedata.init = false;
222
223 /* Used by render-services. */
224 sd->osl_globals = kg;
225 if (path_flag & PATH_RAY_SHADOW) {
226 sd->osl_path_state = nullptr;
227 sd->osl_shadow_path_state = (const IntegratorShadowStateCPU *)state;
228 }
229 else {
230 sd->osl_path_state = (const IntegratorStateCPU *)state;
231 sd->osl_shadow_path_state = nullptr;
232 }
233
234 /* execute shader */
235 OSL::ShadingSystem *ss = (OSL::ShadingSystem *)kg->osl_ss;
236 OSL::ShaderGlobals *globals = &tdata->globals;
237 OSL::ShadingContext *octx = tdata->context;
238 int shader = sd->shader & SHADER_MASK;
239
240 if (kg->osl->volume_state[shader]) {
241#if OSL_LIBRARY_VERSION_CODE >= 11304
242 ss->execute(*octx,
243 *(kg->osl->volume_state[shader]),
244 kg->osl_thread_index,
245 0,
246 *globals,
247 nullptr,
248 nullptr);
249#else
250 ss->execute(octx, *(kg->osl->volume_state[shader]), *globals);
251#endif
252 }
253
254 /* flatten closure tree */
255 if (globals->Ci) {
256 flatten_closure_tree(kg, sd, path_flag, reinterpret_cast<OSLClosure *>(globals->Ci));
257 }
258}
259
260/* Displacement */
261
262template<>
264 const void *state,
265 ShaderData *sd,
266 uint32_t path_flag)
267{
268 /* setup shader globals from shader data */
269 OSLThreadData *tdata = kg->osl_tdata;
271 kg, sd, path_flag, reinterpret_cast<ShaderGlobals *>(&tdata->globals));
272
273 /* clear trace data */
274 tdata->tracedata.init = false;
275
276 /* Used by render-services. */
277 sd->osl_globals = kg;
278 sd->osl_path_state = (const IntegratorStateCPU *)state;
279 sd->osl_shadow_path_state = nullptr;
280
281 /* execute shader */
282 OSL::ShadingSystem *ss = (OSL::ShadingSystem *)kg->osl_ss;
283 OSL::ShaderGlobals *globals = &tdata->globals;
284 OSL::ShadingContext *octx = tdata->context;
285 int shader = sd->shader & SHADER_MASK;
286
287 if (kg->osl->displacement_state[shader]) {
288#if OSL_LIBRARY_VERSION_CODE >= 11304
289 ss->execute(*octx,
290 *(kg->osl->displacement_state[shader]),
291 kg->osl_thread_index,
292 0,
293 *globals,
294 nullptr,
295 nullptr);
296#else
297 ss->execute(octx, *(kg->osl->displacement_state[shader]), *globals);
298#endif
299 }
300
301 /* get back position */
302 sd->P = TO_FLOAT3(globals->P);
303}
304
static ustring u_empty
Definition services.h:354
static ustring u_geom_undisplaced
Definition services.h:327
static void register_closures(OSL::ShadingSystem *ss)
Definition closures.cpp:66
void osl_eval_nodes< SHADER_TYPE_SURFACE >(const KernelGlobalsCPU *kg, const void *state, ShaderData *sd, uint32_t path_flag)
Definition closures.cpp:80
void osl_eval_nodes< SHADER_TYPE_VOLUME >(const KernelGlobalsCPU *kg, const void *state, ShaderData *sd, uint32_t path_flag)
Definition closures.cpp:210
#define TO_FLOAT3(v)
Definition closures.cpp:28
void osl_eval_nodes< SHADER_TYPE_DISPLACEMENT >(const KernelGlobalsCPU *kg, const void *state, ShaderData *sd, uint32_t path_flag)
Definition closures.cpp:263
static OSL::ClosureParam * osl_closure_layer_params()
Definition closures.cpp:58
#define TO_VEC3(v)
Definition closures.cpp:27
#define CCL_NAMESPACE_END
#define offsetof(t, d)
ccl_device_forceinline float differential_make_compact(const float dD)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
ccl_device_inline void object_position_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *P)
ccl_device_inline void object_dir_transform(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private float3 *D)
ccl_device void flatten_closure_tree(KernelGlobals kg, ccl_private ShaderData *sd, uint32_t path_flag, ccl_private const OSLClosure *closure)
CCL_NAMESPACE_BEGIN ccl_device_inline void shaderdata_to_shaderglobals(KernelGlobals kg, ccl_private ShaderData *sd, uint32_t path_flag, ccl_private ShaderGlobals *globals)
@ OSL_CLOSURE_LAYER_ID
@ SD_HAS_DISPLACEMENT
@ PATH_RAY_SHADOW
#define OBJECT_NONE
ShaderData
@ SHADER_MASK
#define LAMP_NONE
static ulong state[N]
unsigned int uint32_t
Definition stdint.h:80