Blender V4.5
services.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5/* TODO(sergey): There is a bit of headers dependency hell going on
6 * here, so for now we just put here. In the future it might be better
7 * to have dedicated file for such tweaks.
8 */
9#if (defined(__GNUC__) && !defined(__clang__)) && defined(NDEBUG)
10# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
11# pragma GCC diagnostic ignored "-Wuninitialized"
12#endif
13
14#include <cstring>
15
16#include "scene/colorspace.h"
17#include "scene/object.h"
18
19#include "util/log.h"
20#include "util/string.h"
21
23
24#include "kernel/osl/globals.h"
25#include "kernel/osl/services.h"
27#include "kernel/osl/types.h"
28
31
34
35#include "kernel/bvh/bvh.h"
36
38
39#include "kernel/svm/ao.h"
40#include "kernel/svm/bevel.h"
41
42#include "kernel/util/ies.h"
43
45
46/* RenderServices implementation */
47
48static void copy_matrix(OSL::Matrix44 &m, const Transform &tfm)
49{
51 memcpy((float *)&m, (const float *)&t, sizeof(m));
52}
53
54static void copy_matrix(OSL::Matrix44 &m, const ProjectionTransform &tfm)
55{
57 memcpy((float *)&m, (const float *)&t, sizeof(m));
58}
59
60/* static ustrings */
61ustring OSLRenderServices::u_distance("distance");
62ustring OSLRenderServices::u_index("index");
63ustring OSLRenderServices::u_world("world");
64ustring OSLRenderServices::u_camera("camera");
65ustring OSLRenderServices::u_screen("screen");
66ustring OSLRenderServices::u_raster("raster");
67ustring OSLRenderServices::u_ndc("NDC");
68ustring OSLRenderServices::u_object_location("object:location");
69ustring OSLRenderServices::u_object_color("object:color");
70ustring OSLRenderServices::u_object_alpha("object:alpha");
71ustring OSLRenderServices::u_object_index("object:index");
72ustring OSLRenderServices::u_object_is_light("object:is_light");
73ustring OSLRenderServices::u_bump_map_normal("geom:bump_map_normal");
74ustring OSLRenderServices::u_geom_dupli_generated("geom:dupli_generated");
75ustring OSLRenderServices::u_geom_dupli_uv("geom:dupli_uv");
76ustring OSLRenderServices::u_material_index("material:index");
77ustring OSLRenderServices::u_object_random("object:random");
78ustring OSLRenderServices::u_particle_index("particle:index");
79ustring OSLRenderServices::u_particle_random("particle:random");
80ustring OSLRenderServices::u_particle_age("particle:age");
81ustring OSLRenderServices::u_particle_lifetime("particle:lifetime");
82ustring OSLRenderServices::u_particle_location("particle:location");
83ustring OSLRenderServices::u_particle_rotation("particle:rotation");
84ustring OSLRenderServices::u_particle_size("particle:size");
85ustring OSLRenderServices::u_particle_velocity("particle:velocity");
86ustring OSLRenderServices::u_particle_angular_velocity("particle:angular_velocity");
87ustring OSLRenderServices::u_geom_numpolyvertices("geom:numpolyvertices");
88ustring OSLRenderServices::u_geom_trianglevertices("geom:trianglevertices");
89ustring OSLRenderServices::u_geom_polyvertices("geom:polyvertices");
90ustring OSLRenderServices::u_geom_name("geom:name");
91ustring OSLRenderServices::u_geom_undisplaced("geom:undisplaced");
92ustring OSLRenderServices::u_is_smooth("geom:is_smooth");
93ustring OSLRenderServices::u_is_curve("geom:is_curve");
94ustring OSLRenderServices::u_curve_thickness("geom:curve_thickness");
95ustring OSLRenderServices::u_curve_length("geom:curve_length");
96ustring OSLRenderServices::u_curve_tangent_normal("geom:curve_tangent_normal");
97ustring OSLRenderServices::u_curve_random("geom:curve_random");
98ustring OSLRenderServices::u_is_point("geom:is_point");
99ustring OSLRenderServices::u_point_radius("geom:point_radius");
100ustring OSLRenderServices::u_point_position("geom:point_position");
101ustring OSLRenderServices::u_point_random("geom:point_random");
102ustring OSLRenderServices::u_normal_map_normal("geom:normal_map_normal");
103ustring OSLRenderServices::u_path_ray_length("path:ray_length");
104ustring OSLRenderServices::u_path_ray_depth("path:ray_depth");
105ustring OSLRenderServices::u_path_diffuse_depth("path:diffuse_depth");
106ustring OSLRenderServices::u_path_glossy_depth("path:glossy_depth");
107ustring OSLRenderServices::u_path_transparent_depth("path:transparent_depth");
108ustring OSLRenderServices::u_path_transmission_depth("path:transmission_depth");
109ustring OSLRenderServices::u_trace("trace");
110ustring OSLRenderServices::u_hit("hit");
111ustring OSLRenderServices::u_hitdist("hitdist");
112ustring OSLRenderServices::u_N("N");
113ustring OSLRenderServices::u_Ng("Ng");
114ustring OSLRenderServices::u_P("P");
115ustring OSLRenderServices::u_I("I");
116ustring OSLRenderServices::u_u("u");
117ustring OSLRenderServices::u_v("v");
119
120ustring OSLRenderServices::u_sensor_size("cam:sensor_size");
121ustring OSLRenderServices::u_image_resolution("cam:image_resolution");
122ustring OSLRenderServices::u_aperture_aspect_ratio("cam:aperture_aspect_ratio");
123ustring OSLRenderServices::u_aperture_size("cam:aperture_size");
124ustring OSLRenderServices::u_aperture_position("cam:aperture_position");
125ustring OSLRenderServices::u_focal_distance("cam:focal_distance");
126
128
129OSLRenderServices::OSLRenderServices(OSL::TextureSystem *texture_system, const int device_type)
130 : OSL::RendererServices(texture_system), device_type_(device_type)
131{
132}
133
135{
136 if (m_texturesys) {
137 VLOG_INFO << "OSL texture system stats:\n" << m_texturesys->getstats();
138 }
139}
140
141int OSLRenderServices::supports(string_view feature) const
142{
143#ifdef WITH_OPTIX
144 if (feature == "OptiX") {
145 return device_type_ == DEVICE_OPTIX;
146 }
147#endif
148
149 return false;
150}
151
152bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
153 OSL::Matrix44 &result,
154 OSL::TransformationPtr xform,
155 const float time)
156{
157 ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
158
159 if (globals == nullptr || globals->sd == nullptr) {
160 return false;
161 }
162
163 /* this is only used for shader and object space, we don't really have
164 * a concept of shader space, so we just use object space for both. */
165 const ShaderData *sd = globals->sd;
166 const ThreadKernelGlobalsCPU *kg = globals->kg;
167 const int object = sd->object;
168
169 if (object != OBJECT_NONE) {
170#ifdef __OBJECT_MOTION__
171 Transform tfm;
172
173 if (time == sd->time) {
174 tfm = object_get_transform(kg, sd);
175 }
176 else {
177 tfm = object_fetch_transform_motion_test(kg, object, time, nullptr);
178 }
179#else
180 const Transform tfm = object_get_transform(kg, sd);
181#endif
182 copy_matrix(result, tfm);
183
184 return true;
185 }
186
187 return false;
188}
189
190bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
191 OSL::Matrix44 &result,
192 OSL::TransformationPtr xform,
193 const float time)
194{
195 ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
196
197 if (globals == nullptr || globals->sd == nullptr) {
198 return false;
199 }
200
201 /* this is only used for shader and object space, we don't really have
202 * a concept of shader space, so we just use object space for both. */
203 const ShaderData *sd = globals->sd;
204 const ThreadKernelGlobalsCPU *kg = globals->kg;
205 const int object = sd->object;
206
207 if (object != OBJECT_NONE) {
208#ifdef __OBJECT_MOTION__
209 Transform itfm;
210
211 if (time == sd->time) {
212 itfm = object_get_inverse_transform(kg, sd);
213 }
214 else {
215 object_fetch_transform_motion_test(kg, object, time, &itfm);
216 }
217#else
218 const Transform itfm = object_get_inverse_transform(kg, sd);
219#endif
220 copy_matrix(result, itfm);
221
222 return true;
223 }
224
225 return false;
226}
227
228bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
229 OSL::Matrix44 &result,
230 OSLUStringHash from,
231 const float time)
232{
233 ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
234 const ThreadKernelGlobalsCPU *kg = globals->kg;
235
236 if (from == u_ndc) {
237 copy_matrix(result, kernel_data.cam.ndctoworld);
238 return true;
239 }
240 if (from == u_raster) {
241 copy_matrix(result, kernel_data.cam.rastertoworld);
242 return true;
243 }
244 if (from == u_screen) {
245 copy_matrix(result, kernel_data.cam.screentoworld);
246 return true;
247 }
248 if (from == u_camera) {
249 copy_matrix(result, kernel_data.cam.cameratoworld);
250 return true;
251 }
252 if (from == u_world) {
253 result.makeIdentity();
254 return true;
255 }
256
257 return false;
258}
259
260bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
261 OSL::Matrix44 &result,
263 const float time)
264{
265 ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
266 const ThreadKernelGlobalsCPU *kg = globals->kg;
267
268 if (to == u_ndc) {
269 copy_matrix(result, kernel_data.cam.worldtondc);
270 return true;
271 }
272 if (to == u_raster) {
273 copy_matrix(result, kernel_data.cam.worldtoraster);
274 return true;
275 }
276 if (to == u_screen) {
277 copy_matrix(result, kernel_data.cam.worldtoscreen);
278 return true;
279 }
280 if (to == u_camera) {
281 copy_matrix(result, kernel_data.cam.worldtocamera);
282 return true;
283 }
284 if (to == u_world) {
285 result.makeIdentity();
286 return true;
287 }
288
289 return false;
290}
291
292bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
293 OSL::Matrix44 &result,
294 OSL::TransformationPtr xform)
295{
296 ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
297
298 if (globals == nullptr || globals->sd == nullptr) {
299 return false;
300 }
301
302 /* this is only used for shader and object space, we don't really have
303 * a concept of shader space, so we just use object space for both. */
304 const ShaderData *sd = globals->sd;
305 const ThreadKernelGlobalsCPU *kg = globals->kg;
306 const int object = sd->object;
307
308 if (object != OBJECT_NONE) {
309 const Transform tfm = object_get_transform(kg, sd);
310 copy_matrix(result, tfm);
311
312 return true;
313 }
314
315 return false;
316}
317
318bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
319 OSL::Matrix44 &result,
320 OSL::TransformationPtr xform)
321{
322 ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
323
324 if (globals == nullptr || globals->sd == nullptr) {
325 return false;
326 }
327
328 /* this is only used for shader and object space, we don't really have
329 * a concept of shader space, so we just use object space for both. */
330 const ShaderData *sd = globals->sd;
331 const ThreadKernelGlobalsCPU *kg = globals->kg;
332 const int object = sd->object;
333
334 if (object != OBJECT_NONE) {
335 const Transform tfm = object_get_inverse_transform(kg, sd);
336 copy_matrix(result, tfm);
337
338 return true;
339 }
340
341 return false;
342}
343
344bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
345 OSL::Matrix44 &result,
346 OSLUStringHash from)
347{
348 ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
349 const ThreadKernelGlobalsCPU *kg = globals->kg;
350
351 if (from == u_ndc) {
352 copy_matrix(result, kernel_data.cam.ndctoworld);
353 return true;
354 }
355 if (from == u_raster) {
356 copy_matrix(result, kernel_data.cam.rastertoworld);
357 return true;
358 }
359 if (from == u_screen) {
360 copy_matrix(result, kernel_data.cam.screentoworld);
361 return true;
362 }
363 if (from == u_camera) {
364 copy_matrix(result, kernel_data.cam.cameratoworld);
365 return true;
366 }
367
368 return false;
369}
370
371bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
372 OSL::Matrix44 &result,
374{
375 ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
376 const ThreadKernelGlobalsCPU *kg = globals->kg;
377
378 if (to == u_ndc) {
379 copy_matrix(result, kernel_data.cam.worldtondc);
380 return true;
381 }
382 if (to == u_raster) {
383 copy_matrix(result, kernel_data.cam.worldtoraster);
384 return true;
385 }
386 if (to == u_screen) {
387 copy_matrix(result, kernel_data.cam.worldtoscreen);
388 return true;
389 }
390 if (to == u_camera) {
391 copy_matrix(result, kernel_data.cam.worldtocamera);
392 return true;
393 }
394
395 return false;
396}
397
398bool OSLRenderServices::get_array_attribute(OSL::ShaderGlobals *sg,
399 bool derivatives,
400 OSLUStringHash object,
401 const TypeDesc type,
402 OSLUStringHash name,
403 const int index,
404 void *val)
405{
406 return false;
407}
408
409template<typename T>
410inline bool set_attribute(
411 const T v, const T dx, const T dy, TypeDesc type, bool derivatives, void *val);
412
413inline void set_data_float(
414 const float v, const float dx, const float dy, bool derivatives, void *val)
415{
416 float *fval = static_cast<float *>(val);
417 fval[0] = v;
418 if (derivatives) {
419 fval[1] = dx;
420 fval[2] = dy;
421 }
422}
423
424inline void set_data_float3(
425 const float3 v, const float3 dx, const float3 dy, bool derivatives, void *val)
426{
427 float *fval = static_cast<float *>(val);
428 fval[0] = v.x;
429 fval[1] = v.y;
430 fval[2] = v.z;
431 if (derivatives) {
432 fval[3] = dx.x;
433 fval[4] = dx.y;
434 fval[5] = dx.z;
435 fval[6] = dy.x;
436 fval[7] = dy.y;
437 fval[8] = dy.z;
438 }
439}
440
441inline void set_data_float4(
442 const float4 v, const float4 dx, const float4 dy, bool derivatives, void *val)
443{
444 float *fval = static_cast<float *>(val);
445 fval[0] = v.x;
446 fval[1] = v.y;
447 fval[2] = v.z;
448 fval[3] = v.w;
449 if (derivatives) {
450 fval[4] = dx.x;
451 fval[5] = dx.y;
452 fval[6] = dx.z;
453 fval[7] = dx.w;
454 fval[8] = dy.x;
455 fval[9] = dy.y;
456 fval[10] = dy.z;
457 fval[11] = dy.w;
458 }
459}
460
462 const float v, const float dx, const float dy, TypeDesc type, bool derivatives, void *val)
463{
464 if (type == TypeFloatArray4) {
466 make_float4(dx, dx, dx, 0.0f),
467 make_float4(dy, dy, dy, 0.0f),
468 derivatives,
469 val);
470 return true;
471 }
472 if (type == TypePoint || type == TypeVector || type == TypeNormal || type == TypeColor) {
473 set_data_float3(make_float3(v), make_float3(dx), make_float3(dy), derivatives, val);
474 return true;
475 }
476 if (type == TypeFloat) {
477 set_data_float(v, dx, dy, derivatives, val);
478 return true;
479 }
480
481 return false;
482}
483
485 const float2 v, const float2 dx, const float2 dy, TypeDesc type, bool derivatives, void *val)
486{
487 if (type == TypeFloatArray4) {
488 set_data_float4(make_float4(v.x, v.y, 0.0f, 1.0f),
489 make_float4(dx.x, dx.y, 0.0f, 0.0f),
490 make_float4(dy.x, dy.y, 0.0f, 0.0f),
491 derivatives,
492 val);
493 return true;
494 }
495 if (type == TypePoint || type == TypeVector || type == TypeNormal || type == TypeColor) {
496 set_data_float3(make_float3(v), make_float3(dx), make_float3(dy), derivatives, val);
497 return true;
498 }
499 if (type == TypeFloat) {
500 set_data_float(average(v), average(dx), average(dy), derivatives, val);
501 return true;
502 }
503
504 return false;
505}
506
508 const float3 v, const float3 dx, const float3 dy, TypeDesc type, bool derivatives, void *val)
509{
510 if (type == TypeFloatArray4) {
512 make_float4(v, 1.0f), make_float4(dx, 0.0f), make_float4(dy, 0.0f), derivatives, val);
513 return true;
514 }
515 if (type == TypePoint || type == TypeVector || type == TypeNormal || type == TypeColor) {
516 set_data_float3(v, dx, dy, derivatives, val);
517 return true;
518 }
519 if (type == TypeFloat) {
520 set_data_float(average(v), average(dx), average(dy), derivatives, val);
521 return true;
522 }
523
524 return false;
525}
526
527/* Attributes with the TypeRGBA type descriptor should be retrieved and stored
528 * in a float array of size 4 (e.g. node_vertex_color.osl), this array have
529 * a type descriptor TypeFloatArray4. If the storage is not a TypeFloatArray4,
530 * we either store the first three components in a vector, store the average of
531 * the components in a float, or fail the retrieval and do nothing. We allow
532 * this for the correct operation of the Attribute node.
533 */
534
536 const float4 v, const float4 dx, const float4 dy, TypeDesc type, bool derivatives, void *val)
537{
538 if (type == TypeFloatArray4) {
539 set_data_float4(v, dx, dy, derivatives, val);
540 return true;
541 }
542 if (type == TypePoint || type == TypeVector || type == TypeNormal || type == TypeColor) {
543 set_data_float3(make_float3(v), make_float3(dx), make_float3(dy), derivatives, val);
544 return true;
545 }
546 if (type == TypeFloat) {
548 average(make_float3(dx)),
549 average(make_float3(dy)),
550 derivatives,
551 val);
552 return true;
553 }
554 return false;
555}
556
557template<typename T>
558ccl_device_inline bool set_attribute(const T f, const TypeDesc type, bool derivatives, void *val)
559{
560 return set_attribute(f, make_zero<T>(), make_zero<T>(), type, derivatives, val);
561}
562
564 const TypeDesc type,
565 bool derivatives,
566 void *val)
567{
568 if (type.basetype == TypeDesc::INT && type.aggregate == TypeDesc::SCALAR && type.arraylen == 0) {
569 int *ival = (int *)val;
570 ival[0] = i;
571
572 if (derivatives) {
573 ival[1] = 0;
574 ival[2] = 0;
575 }
576
577 return true;
578 }
579
580 return false;
581}
582
584 const TypeDesc type,
585 bool derivatives,
586 void *val)
587{
588 if (type.basetype == TypeDesc::STRING && type.aggregate == TypeDesc::SCALAR &&
589 type.arraylen == 0)
590 {
591 OSLUStringHash *sval = (OSLUStringHash *)val;
592 sval[0] = str;
593
594 if (derivatives) {
595 sval[1] = OSLUStringHash();
596 sval[2] = OSLUStringHash();
597 }
598
599 return true;
600 }
601
602 return false;
603}
604
605static bool set_attribute_float3_3(const float3 P[3], TypeDesc type, bool derivatives, void *val)
606{
607 if (type.vecsemantics == TypeDesc::POINT && type.arraylen >= 3) {
608 float *fval = (float *)val;
609
610 fval[0] = P[0].x;
611 fval[1] = P[0].y;
612 fval[2] = P[0].z;
613
614 fval[3] = P[1].x;
615 fval[4] = P[1].y;
616 fval[5] = P[1].z;
617
618 fval[6] = P[2].x;
619 fval[7] = P[2].y;
620 fval[8] = P[2].z;
621
622 if (type.arraylen > 3) {
623 memset(fval + 3 * 3, 0, sizeof(float) * 3 * (type.arraylen - 3));
624 }
625 if (derivatives) {
626 memset(fval + type.arraylen * 3, 0, sizeof(float) * 2 * 3 * type.arraylen);
627 }
628
629 return true;
630 }
631
632 return false;
633}
634
635static bool set_attribute_matrix(const Transform &tfm, const TypeDesc type, void *val)
636{
637 if (type == TypeMatrix) {
638 copy_matrix(*(OSL::Matrix44 *)val, tfm);
639 return true;
640 }
641
642 return false;
643}
644
645template<typename T>
647 ShaderData *sd,
648 const AttributeDescriptor &desc,
649 const TypeDesc &type,
650 bool derivatives,
651 void *val)
652{
653 T v;
654 T dx = make_zero<T>();
655 T dy = make_zero<T>();
656#ifdef __VOLUME__
657 if (primitive_is_volume_attribute(sd, desc)) {
658 v = primitive_volume_attribute<T>(kg, sd, desc);
659 }
660 else
661#endif
662 {
664 kg, sd, desc, derivatives ? &dx : nullptr, derivatives ? &dy : nullptr);
665 }
666 return set_attribute(v, dx, dy, type, derivatives, val);
667}
668
670 ShaderData *sd,
671 const AttributeDescriptor &desc,
672 const TypeDesc &type,
673 bool derivatives,
674 void *val)
675{
676 if (desc.type == NODE_ATTR_FLOAT) {
677 return get_object_attribute_impl<float>(kg, sd, desc, type, derivatives, val);
678 }
679 else if (desc.type == NODE_ATTR_FLOAT2) {
680 return get_object_attribute_impl<float2>(kg, sd, desc, type, derivatives, val);
681 }
682 else if (desc.type == NODE_ATTR_FLOAT3) {
683 return get_object_attribute_impl<float3>(kg, sd, desc, type, derivatives, val);
684 }
685 else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
686 return get_object_attribute_impl<float4>(kg, sd, desc, type, derivatives, val);
687 }
688 else if (desc.type == NODE_ATTR_MATRIX) {
689 const Transform tfm = primitive_attribute_matrix(kg, desc);
690 return set_attribute_matrix(tfm, type, val);
691 }
692 return false;
693}
694
696 ShaderGlobals *globals, OSLUStringHash name, const TypeDesc type, bool derivatives, void *val)
697{
698 ShaderData *sd = globals->sd;
699 const ThreadKernelGlobalsCPU *kg = globals->kg;
700 /* todo: turn this into hash table? */
701
702 /* Object Attributes */
703 if (name == u_object_location) {
704 const float3 f = object_location(kg, sd);
705 return set_attribute(f, type, derivatives, val);
706 }
707 if (name == u_object_color) {
708 const float3 f = object_color(kg, sd->object);
709 return set_attribute(f, type, derivatives, val);
710 }
711 if (name == u_object_alpha) {
712 const float f = object_alpha(kg, sd->object);
713 return set_attribute(f, type, derivatives, val);
714 }
715 if (name == u_object_index) {
716 const float f = object_pass_id(kg, sd->object);
717 return set_attribute(f, type, derivatives, val);
718 }
719 if (name == u_object_is_light) {
720 const float f = (sd->type & PRIMITIVE_LAMP) != 0;
721 return set_attribute(f, type, derivatives, val);
722 }
723 if (name == u_geom_dupli_generated) {
724 const float3 f = object_dupli_generated(kg, sd->object);
725 return set_attribute(f, type, derivatives, val);
726 }
727 if (name == u_geom_dupli_uv) {
728 const float3 f = object_dupli_uv(kg, sd->object);
729 return set_attribute(f, type, derivatives, val);
730 }
731 if (name == u_material_index) {
732 const float f = shader_pass_id(kg, sd);
733 return set_attribute(f, type, derivatives, val);
734 }
735 if (name == u_object_random) {
736 const float f = object_random_number(kg, sd->object);
737 return set_attribute(f, type, derivatives, val);
738 }
739
740 /* Particle Attributes */
741 if (name == u_particle_index) {
742 const int particle_id = object_particle_id(kg, sd->object);
743 const float f = particle_index(kg, particle_id);
744 return set_attribute(f, type, derivatives, val);
745 }
746 if (name == u_particle_random) {
747 const int particle_id = object_particle_id(kg, sd->object);
748 const float f = hash_uint2_to_float(particle_index(kg, particle_id), 0);
749 return set_attribute(f, type, derivatives, val);
750 }
751 if (name == u_particle_age) {
752 const int particle_id = object_particle_id(kg, sd->object);
753 const float f = particle_age(kg, particle_id);
754 return set_attribute(f, type, derivatives, val);
755 }
756 if (name == u_particle_lifetime) {
757 const int particle_id = object_particle_id(kg, sd->object);
758 const float f = particle_lifetime(kg, particle_id);
759 return set_attribute(f, type, derivatives, val);
760 }
761 if (name == u_particle_location) {
762 const int particle_id = object_particle_id(kg, sd->object);
763 const float3 f = particle_location(kg, particle_id);
764 return set_attribute(f, type, derivatives, val);
765 }
766#if 0 /* unsupported */
767 if (name == u_particle_rotation) {
768 int particle_id = object_particle_id(kg, sd->object);
769 float4 f = particle_rotation(kg, particle_id);
770 return set_attribute(f, type, derivatives, val);
771 }
772#endif
773 if (name == u_particle_size) {
774 const int particle_id = object_particle_id(kg, sd->object);
775 const float f = particle_size(kg, particle_id);
776 return set_attribute(f, type, derivatives, val);
777 }
778 if (name == u_particle_velocity) {
779 const int particle_id = object_particle_id(kg, sd->object);
780 const float3 f = particle_velocity(kg, particle_id);
781 return set_attribute(f, type, derivatives, val);
782 }
783 if (name == u_particle_angular_velocity) {
784 const int particle_id = object_particle_id(kg, sd->object);
785 const float3 f = particle_angular_velocity(kg, particle_id);
786 return set_attribute(f, type, derivatives, val);
787 }
788
789 /* Geometry Attributes */
790 if (name == u_geom_numpolyvertices) {
791 return set_attribute(3, type, derivatives, val);
792 }
793 if ((name == u_geom_trianglevertices || name == u_geom_polyvertices) &&
794 sd->type & PRIMITIVE_TRIANGLE)
795 {
796 float3 P[3];
797
798 if (sd->type & PRIMITIVE_MOTION) {
799 motion_triangle_vertices(kg, sd->object, sd->prim, sd->time, P);
800 }
801 else {
802 triangle_vertices(kg, sd->prim, P);
803 }
804
805 if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
806 object_position_transform(kg, sd, &P[0]);
807 object_position_transform(kg, sd, &P[1]);
808 object_position_transform(kg, sd, &P[2]);
809 }
810
811 return set_attribute_float3_3(P, type, derivatives, val);
812 }
813 if (name == u_geom_name) {
814 const ustring object_name = kg->osl.globals->object_names[sd->object];
815 return set_attribute(object_name, type, derivatives, val);
816 }
817 if (name == u_is_smooth) {
818 const float f = ((sd->shader & SHADER_SMOOTH_NORMAL) != 0);
819 return set_attribute(f, type, derivatives, val);
820 }
821#ifdef __HAIR__
822 /* Hair Attributes */
823 if (name == u_is_curve) {
824 const float f = (sd->type & PRIMITIVE_CURVE) != 0;
825 return set_attribute(f, type, derivatives, val);
826 }
827 if (name == u_curve_thickness) {
828 const float f = curve_thickness(kg, sd);
829 return set_attribute(f, type, derivatives, val);
830 }
831 if (name == u_curve_tangent_normal) {
832 const float3 f = curve_tangent_normal(kg, sd);
833 return set_attribute(f, type, derivatives, val);
834 }
835 if (name == u_curve_random) {
836 const float f = curve_random(kg, sd);
837 return set_attribute(f, type, derivatives, val);
838 }
839#endif
840#ifdef __POINTCLOUD__
841 /* point attributes */
842 if (name == u_is_point) {
843 const float f = (sd->type & PRIMITIVE_POINT) != 0;
844 return set_attribute(f, type, derivatives, val);
845 }
846 if (name == u_point_radius) {
847 const float f = point_radius(kg, sd);
848 return set_attribute(f, type, derivatives, val);
849 }
850 if (name == u_point_position) {
851 const float3 f = point_position(kg, sd);
852 return set_attribute(f, type, derivatives, val);
853 }
854 if (name == u_point_random) {
855 const float f = point_random(kg, sd);
856 return set_attribute(f, type, derivatives, val);
857 }
858#endif
859 if (name == u_normal_map_normal) {
860 if (sd->type & PRIMITIVE_TRIANGLE) {
861 const float3 f = triangle_smooth_normal_unnormalized(kg, sd, sd->Ng, sd->prim, sd->u, sd->v);
862 return set_attribute(f, type, derivatives, val);
863 }
864 return false;
865 }
866 if (name == u_bump_map_normal) {
867 float3 f[3];
868 if (!attribute_bump_map_normal(kg, sd, f)) {
869 return false;
870 }
871 return set_attribute(f[0], f[1], f[2], type, derivatives, val);
872 }
873 return get_background_attribute(globals, name, type, derivatives, val);
874}
875
877 ShaderGlobals *globals, OSLUStringHash name, const TypeDesc type, bool derivatives, void *val)
878{
879 ShaderData *sd = globals->sd;
880 const ThreadKernelGlobalsCPU *kg = globals->kg;
881 const IntegratorStateCPU *state = globals->path_state;
882 const IntegratorShadowStateCPU *shadow_state = globals->shadow_path_state;
883 if (name == u_path_ray_length) {
884 /* Ray Length */
885 const float f = sd->ray_length;
886 return set_attribute(f, type, derivatives, val);
887 }
888
889#define READ_PATH_STATE(elem) \
890 ((state != nullptr) ? state->path.elem : \
891 (shadow_state != nullptr) ? shadow_state->shadow_path.elem : \
892 0)
893
894 if (name == u_path_ray_depth) {
895 /* Ray Depth */
896 int f = READ_PATH_STATE(bounce);
897
898 /* Read bounce from different locations depending on if this is a shadow path. For background,
899 * light emission and shadow evaluation from a surface or volume we are effectively one bounce
900 * further. */
901 if (globals->raytype & (PATH_RAY_SHADOW | PATH_RAY_EMISSION)) {
902 f += 1;
903 }
904
905 return set_attribute(f, type, derivatives, val);
906 }
907 if (name == u_path_diffuse_depth) {
908 /* Diffuse Ray Depth */
909 const int f = READ_PATH_STATE(diffuse_bounce);
910 return set_attribute(f, type, derivatives, val);
911 }
912 if (name == u_path_glossy_depth) {
913 /* Glossy Ray Depth */
914 const int f = READ_PATH_STATE(glossy_bounce);
915 return set_attribute(f, type, derivatives, val);
916 }
917 if (name == u_path_transmission_depth) {
918 /* Transmission Ray Depth */
919 const int f = READ_PATH_STATE(transmission_bounce);
920 return set_attribute(f, type, derivatives, val);
921 }
922 if (name == u_path_transparent_depth) {
923 /* Transparent Ray Depth */
924 const int f = READ_PATH_STATE(transparent_bounce);
925 return set_attribute(f, type, derivatives, val);
926 }
927#undef READ_PATH_STATE
928
929 if (name == u_ndc) {
930 /* NDC coordinates with special exception for orthographic projection. */
931 float3 ndc[3];
932
933 if ((globals->raytype & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE &&
935 {
936 ndc[0] = camera_world_to_ndc(kg, sd, sd->ray_P);
937
938 if (derivatives) {
939 ndc[1] = zero_float3();
940 ndc[2] = zero_float3();
941 }
942 }
943 else {
944 ndc[0] = camera_world_to_ndc(kg, sd, sd->P);
945
946 if (derivatives) {
947 const differential3 dP = differential_from_compact(sd->Ng, sd->dP);
948 ndc[1] = camera_world_to_ndc(kg, sd, sd->P + dP.dx) - ndc[0];
949 ndc[2] = camera_world_to_ndc(kg, sd, sd->P + dP.dy) - ndc[0];
950 }
951 }
952
953 return set_attribute(ndc[0], ndc[1], ndc[2], type, derivatives, val);
954 }
955
956 return false;
957}
958
960 ShaderGlobals *globals, OSLUStringHash name, TypeDesc type, bool derivatives, void *val)
961{
962 const ThreadKernelGlobalsCPU *kg = globals->kg;
963 if (name == u_sensor_size) {
964 const float2 sensor = make_float2(kernel_data.cam.sensorwidth, kernel_data.cam.sensorheight);
965 return set_attribute(sensor, type, derivatives, val);
966 }
967 else if (name == u_image_resolution) {
968 const float2 image = make_float2(kernel_data.cam.width, kernel_data.cam.height);
969 return set_attribute(image, type, derivatives, val);
970 }
971 else if (name == u_aperture_aspect_ratio) {
972 return set_attribute(1.0f / kernel_data.cam.inv_aperture_ratio, type, derivatives, val);
973 }
974 else if (name == u_aperture_size) {
975 return set_attribute(kernel_data.cam.aperturesize, type, derivatives, val);
976 }
977 else if (name == u_aperture_position) {
978 /* The random numbers for aperture sampling are packed into N. */
979 const float2 rand_lens = make_float2(globals->N.x, globals->N.y);
980 const float2 pos = camera_sample_aperture(&kernel_data.cam, rand_lens);
981 return set_attribute(pos * kernel_data.cam.aperturesize, type, derivatives, val);
982 }
983 else if (name == u_focal_distance) {
984 return set_attribute(kernel_data.cam.focaldistance, type, derivatives, val);
985 }
986 return false;
987}
988
989bool OSLRenderServices::get_attribute(OSL::ShaderGlobals *sg,
990 bool derivatives,
991 OSLUStringHash object_name,
992 const TypeDesc type,
993 OSLUStringHash name,
994 void *val)
995{
996 ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
997 if (globals == nullptr) {
998 return false;
999 }
1000
1001 ShaderData *sd = globals->sd;
1002 const ThreadKernelGlobalsCPU *kg = globals->kg;
1003 if (sd == nullptr) {
1004 /* Camera shader. */
1005 return get_camera_attribute(globals, name, type, derivatives, val);
1006 }
1007
1008 /* lookup of attribute on another object */
1009 int object;
1010 if (object_name != u_empty) {
1011 const OSLGlobals::ObjectNameMap::iterator it = kg->osl.globals->object_name_map.find(
1012 object_name);
1013
1014 if (it == kg->osl.globals->object_name_map.end()) {
1015 return false;
1016 }
1017
1018 object = it->second;
1019 }
1020 else {
1021 object = sd->object;
1022 }
1023
1024 /* find attribute on object */
1025 const AttributeDescriptor desc = find_attribute(kg, object, sd->prim, name.hash());
1026 if (desc.offset != ATTR_STD_NOT_FOUND) {
1027 return get_object_attribute(kg, sd, desc, type, derivatives, val);
1028 }
1029
1030 /* not found in attribute, check standard object info */
1031 return get_object_standard_attribute(globals, name, type, derivatives, val);
1032}
1033
1035 bool derivatives, OSLUStringHash name, const TypeDesc type, OSL::ShaderGlobals *sg, void *val)
1036{
1037 return false; /* disabled by lockgeom */
1038}
1039
1040OSL::TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(
1041 OSLUStringHash filename, OSL::ShadingContext *context, const OSL::TextureOpt *opt)
1042{
1043 return get_texture_handle(to_ustring(filename), context, opt);
1044}
1045
1046OSL::TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(
1047 OSL::ustring filename, OSL::ShadingContext * /*context*/, const OSL::TextureOpt * /*options*/)
1048{
1049 OSLTextureHandleMap::iterator it = textures.find(filename);
1050
1051 if (device_type_ == DEVICE_CPU) {
1052 /* For non-OIIO textures, just return a pointer to our own OSLTextureHandle. */
1053 if (it != textures.end()) {
1054 if (it->second.type != OSLTextureHandle::OIIO) {
1055 return (OSL::TextureSystem::TextureHandle *)(&it->second);
1056 }
1057 }
1058
1059 /* Get handle from OpenImageIO. */
1060 OSL::TextureSystem *ts = m_texturesys;
1061 OSL::TextureSystem::TextureHandle *handle = ts->get_texture_handle(to_ustring(filename));
1062 if (handle == nullptr) {
1063 return nullptr;
1064 }
1065
1066 /* Insert new OSLTextureHandle if needed. */
1067 if (it == textures.end()) {
1069 it = textures.find(filename);
1070 }
1071
1072 /* Assign OIIO texture handle and return.
1073 * OIIO::unordered_map_concurrent always returns a const handle even if the underlying
1074 * std::unordered_map supports updating values just fine. */
1075 const_cast<OSLTextureHandle &>(it->second).oiio_handle = handle;
1076 return (OSL::TextureSystem::TextureHandle *)(&it->second);
1077 }
1078
1079 /* Construct GPU texture handle for existing textures. */
1080 if (it != textures.end()) {
1081 switch (it->second.type) {
1083 return nullptr;
1085 if (!it->second.handle.empty() && it->second.handle.get_manager() != image_manager) {
1086 it.clear();
1087 break;
1088 }
1089 return reinterpret_cast<OSL::TextureSystem::TextureHandle *>(OSL_TEXTURE_HANDLE_TYPE_SVM |
1090 it->second.svm_slots[0].y);
1092 if (!it->second.handle.empty() && it->second.handle.get_manager() != image_manager) {
1093 it.clear();
1094 break;
1095 }
1096 return reinterpret_cast<OSL::TextureSystem::TextureHandle *>(OSL_TEXTURE_HANDLE_TYPE_IES |
1097 it->second.svm_slots[0].y);
1099 return reinterpret_cast<OSL::TextureSystem::TextureHandle *>(
1102 return reinterpret_cast<OSL::TextureSystem::TextureHandle *>(
1104 }
1105 }
1106
1107 if (!image_manager) {
1108 return nullptr;
1109 }
1110
1111 /* Load new textures using SVM image manager. */
1112 const ImageHandle handle = image_manager->add_image(filename.string(), ImageParams());
1113 if (handle.empty()) {
1114 return nullptr;
1115 }
1116
1117 if (!textures.insert(filename, OSLTextureHandle(handle))) {
1118 return nullptr;
1119 }
1120
1121 return reinterpret_cast<OSL::TextureSystem::TextureHandle *>(OSL_TEXTURE_HANDLE_TYPE_SVM |
1122 handle.svm_slot());
1123}
1124
1125bool OSLRenderServices::good(OSL::TextureSystem::TextureHandle *texture_handle)
1126{
1127 OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
1128
1129 if (handle->oiio_handle) {
1130 OSL::TextureSystem *ts = m_texturesys;
1131 return ts->good(handle->oiio_handle);
1132 }
1133 return true;
1134}
1135
1137 TextureHandle *texture_handle,
1138 TexturePerthread *texture_thread_info,
1139 OSL::TextureOpt &options,
1140 OSL::ShaderGlobals *sg,
1141 float s,
1142 float t,
1143 const float dsdx,
1144 const float dtdx,
1145 const float dsdy,
1146 const float dtdy,
1147 const int nchannels,
1148 float *result,
1149 float *dresultds,
1150 float *dresultdt,
1151 OSLUStringHash *errormessage)
1152{
1153 OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
1154 const OSLTextureHandle::Type texture_type = (handle) ? handle->type : OSLTextureHandle::OIIO;
1155 ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
1156 ShaderData *sd = globals->sd;
1157 const ThreadKernelGlobalsCPU *kernel_globals = globals->kg;
1158 const IntegratorStateCPU *state = globals->path_state;
1159 bool status = false;
1160
1161 switch (texture_type) {
1163#ifdef __SHADER_RAYTRACE__
1164 /* Bevel shader hack. */
1165 if (nchannels >= 3 && state != nullptr) {
1166 const int num_samples = (int)s;
1167 const float radius = t;
1168 const float3 N = svm_bevel(kernel_globals, state, sd, radius, num_samples);
1169 result[0] = N.x;
1170 result[1] = N.y;
1171 result[2] = N.z;
1172 status = true;
1173 }
1174#endif
1175 break;
1176 }
1177 case OSLTextureHandle::AO: {
1178#ifdef __SHADER_RAYTRACE__
1179 /* AO shader hack. */
1180 if (state != nullptr) {
1181 const int num_samples = (int)s;
1182 const float radius = t;
1183 const float3 N = make_float3(dsdx, dtdx, dsdy);
1184 int flags = 0;
1185 if ((int)dtdy) {
1186 flags |= NODE_AO_INSIDE;
1187 }
1188 if ((int)options.sblur) {
1189 flags |= NODE_AO_ONLY_LOCAL;
1190 }
1191 if ((int)options.tblur) {
1192 flags |= NODE_AO_GLOBAL_RADIUS;
1193 }
1194 result[0] = svm_ao(kernel_globals, state, sd, N, radius, num_samples, flags);
1195 status = true;
1196 }
1197#endif
1198 break;
1199 }
1200 case OSLTextureHandle::SVM: {
1201 int id = -1;
1202 if (handle->svm_slots[0].w == -1) {
1203 /* Packed single texture. */
1204 id = handle->svm_slots[0].y;
1205 }
1206 else {
1207 /* Packed tiled texture. */
1208 const int tx = (int)s;
1209 const int ty = (int)t;
1210 const int tile = 1001 + 10 * ty + tx;
1211 for (const int4 &tile_node : handle->svm_slots) {
1212 if (tile_node.x == tile) {
1213 id = tile_node.y;
1214 break;
1215 }
1216 if (tile_node.z == tile) {
1217 id = tile_node.w;
1218 break;
1219 }
1220 }
1221 s -= tx;
1222 t -= ty;
1223 }
1224
1225 float4 rgba;
1226 if (id == -1) {
1227 rgba = make_float4(
1229 }
1230 else {
1231 rgba = kernel_tex_image_interp(kernel_globals, id, s, 1.0f - t);
1232 }
1233
1234 result[0] = rgba[0];
1235 if (nchannels > 1) {
1236 result[1] = rgba[1];
1237 }
1238 if (nchannels > 2) {
1239 result[2] = rgba[2];
1240 }
1241 if (nchannels > 3) {
1242 result[3] = rgba[3];
1243 }
1244 status = true;
1245 break;
1246 }
1247 case OSLTextureHandle::IES: {
1248 /* IES light. */
1249 result[0] = kernel_ies_interp(kernel_globals, handle->svm_slots[0].y, s, t);
1250 status = true;
1251 break;
1252 }
1254 /* OpenImageIO texture cache. */
1255 OSL::TextureSystem *ts = m_texturesys;
1256
1257 if (handle && handle->oiio_handle) {
1258 if (texture_thread_info == nullptr) {
1259 texture_thread_info = kernel_globals->osl.oiio_thread_info;
1260 }
1261
1262 status = ts->texture(handle->oiio_handle,
1263 texture_thread_info,
1264 options,
1265 s,
1266 t,
1267 dsdx,
1268 dtdx,
1269 dsdy,
1270 dtdy,
1271 nchannels,
1272 result,
1273 dresultds,
1274 dresultdt);
1275 }
1276 else {
1277 status = ts->texture(to_ustring(filename),
1278 options,
1279 s,
1280 t,
1281 dsdx,
1282 dtdx,
1283 dsdy,
1284 dtdy,
1285 nchannels,
1286 result,
1287 dresultds,
1288 dresultdt);
1289 }
1290
1291 if (!status) {
1292 /* This might be slow, but prevents error messages leak and
1293 * other nasty stuff happening. */
1294 ts->geterror();
1295 }
1296 else if (handle && handle->processor) {
1298 }
1299 break;
1300 }
1301 }
1302
1303 if (!status) {
1304 if (nchannels == 3 || nchannels == 4) {
1305 result[0] = 1.0f;
1306 result[1] = 0.0f;
1307 result[2] = 1.0f;
1308
1309 if (nchannels == 4) {
1310 result[3] = 1.0f;
1311 }
1312 }
1313 }
1314
1315 return status;
1316}
1317
1319 TextureHandle *texture_handle,
1320 TexturePerthread *texture_thread_info,
1321 OSL::TextureOpt &options,
1322 OSL::ShaderGlobals *sg,
1323 const OSL::Vec3 &P,
1324 const OSL::Vec3 &dPdx,
1325 const OSL::Vec3 &dPdy,
1326 const OSL::Vec3 &dPdz,
1327 const int nchannels,
1328 float *result,
1329 float *dresultds,
1330 float *dresultdt,
1331 float *dresultdr,
1332 OSLUStringHash *errormessage)
1333{
1334 OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
1335 const OSLTextureHandle::Type texture_type = (handle) ? handle->type : OSLTextureHandle::OIIO;
1336 ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
1337 const ThreadKernelGlobalsCPU *kernel_globals = globals->kg;
1338 bool status = false;
1339
1340 switch (texture_type) {
1341 case OSLTextureHandle::SVM: {
1342 /* Packed texture. */
1343 const int slot = handle->svm_slots[0].y;
1344 const float3 P_float3 = make_float3(P.x, P.y, P.z);
1345 float4 rgba = kernel_tex_image_interp_3d(kernel_globals, slot, P_float3, INTERPOLATION_NONE);
1346
1347 result[0] = rgba[0];
1348 if (nchannels > 1) {
1349 result[1] = rgba[1];
1350 }
1351 if (nchannels > 2) {
1352 result[2] = rgba[2];
1353 }
1354 if (nchannels > 3) {
1355 result[3] = rgba[3];
1356 }
1357 status = true;
1358 break;
1359 }
1361 /* OpenImageIO texture cache. */
1362 OSL::TextureSystem *ts = m_texturesys;
1363
1364 if (handle && handle->oiio_handle) {
1365 if (texture_thread_info == nullptr) {
1366 texture_thread_info = kernel_globals->osl.oiio_thread_info;
1367 }
1368
1369 status = ts->texture3d(handle->oiio_handle,
1370 texture_thread_info,
1371 options,
1372 P,
1373 dPdx,
1374 dPdy,
1375 dPdz,
1376 nchannels,
1377 result,
1378 dresultds,
1379 dresultdt,
1380 dresultdr);
1381 }
1382 else {
1383 status = ts->texture3d(to_ustring(filename),
1384 options,
1385 P,
1386 dPdx,
1387 dPdy,
1388 dPdz,
1389 nchannels,
1390 result,
1391 dresultds,
1392 dresultdt,
1393 dresultdr);
1394 }
1395
1396 if (!status) {
1397 /* This might be slow, but prevents error messages leak and
1398 * other nasty stuff happening. */
1399 ts->geterror();
1400 }
1401 else if (handle && handle->processor) {
1403 }
1404 break;
1405 }
1409 status = false;
1410 break;
1411 }
1412 }
1413
1414 if (!status) {
1415 if (nchannels == 3 || nchannels == 4) {
1416 result[0] = 1.0f;
1417 result[1] = 0.0f;
1418 result[2] = 1.0f;
1419
1420 if (nchannels == 4) {
1421 result[3] = 1.0f;
1422 }
1423 }
1424 }
1425
1426 return status;
1427}
1428
1430 TextureHandle *texture_handle,
1431 TexturePerthread *thread_info,
1432 OSL::TextureOpt &options,
1433 OSL::ShaderGlobals *sg,
1434 const OSL::Vec3 &R,
1435 const OSL::Vec3 &dRdx,
1436 const OSL::Vec3 &dRdy,
1437 const int nchannels,
1438 float *result,
1439 float *dresultds,
1440 float *dresultdt,
1441 OSLUStringHash *errormessage)
1442{
1443 OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
1444 OSL::TextureSystem *ts = m_texturesys;
1445 ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
1446 bool status = false;
1447
1448 if (handle && handle->oiio_handle) {
1449 if (thread_info == nullptr) {
1450 thread_info = globals->kg->osl.oiio_thread_info;
1451 }
1452
1453 status = ts->environment(handle->oiio_handle,
1454 thread_info,
1455 options,
1456 R,
1457 dRdx,
1458 dRdy,
1459 nchannels,
1460 result,
1461 dresultds,
1462 dresultdt);
1463 }
1464 else {
1465 status = ts->environment(
1466 to_ustring(filename), options, R, dRdx, dRdy, nchannels, result, dresultds, dresultdt);
1467 }
1468
1469 if (!status) {
1470 if (nchannels == 3 || nchannels == 4) {
1471 result[0] = 1.0f;
1472 result[1] = 0.0f;
1473 result[2] = 1.0f;
1474
1475 if (nchannels == 4) {
1476 result[3] = 1.0f;
1477 }
1478 }
1479 }
1480 else if (handle && handle->processor) {
1482 }
1483
1484 return status;
1485}
1486
1488 TextureHandle *texture_handle,
1489 TexturePerthread *texture_thread_info,
1490 OSL::ShaderGlobals * /*sg*/,
1491 const int subimage,
1492 OSLUStringHash dataname,
1493 const TypeDesc datatype,
1494 void *data,
1495 OSLUStringHash * /*errormessage*/)
1496{
1497 OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
1498 OSL::TextureSystem *ts = m_texturesys;
1499
1500 if (handle) {
1501 /* No texture info for other texture types. */
1502 if (handle->type != OSLTextureHandle::OIIO) {
1503 return false;
1504 }
1505
1506 if (handle->oiio_handle) {
1507 /* Get texture info from OpenImageIO. */
1508 return ts->get_texture_info(handle->oiio_handle,
1509 texture_thread_info,
1510 subimage,
1511 to_ustring(dataname),
1512 datatype,
1513 data);
1514 }
1515 }
1516
1517 /* Get texture info from OpenImageIO, slower using filename. */
1518 return ts->get_texture_info(
1519 to_ustring(filename), subimage, to_ustring(dataname), datatype, data);
1520}
1521
1522int OSLRenderServices::pointcloud_search(OSL::ShaderGlobals *sg,
1523 OSLUStringHash filename,
1524 const OSL::Vec3 &center,
1525 const float radius,
1526 const int max_points,
1527 bool sort,
1528#if OSL_LIBRARY_VERSION_CODE >= 11400
1529 int *indices,
1530#else
1531 size_t *out_indices,
1532#endif
1533 float *out_distances,
1534 const int derivs_offset)
1535{
1536 return 0;
1537}
1538
1539int OSLRenderServices::pointcloud_get(OSL::ShaderGlobals *sg,
1540 OSLUStringHash filename,
1541#if OSL_LIBRARY_VERSION_CODE >= 11400
1542 const int *indices,
1543#else
1544 size_t *indices,
1545#endif
1546 const int count,
1547 OSLUStringHash attr_name,
1548 const TypeDesc attr_type,
1549 void *out_data)
1550{
1551 return 0;
1552}
1553
1554bool OSLRenderServices::pointcloud_write(OSL::ShaderGlobals *sg,
1555 OSLUStringHash filename,
1556 const OSL::Vec3 &pos,
1557 const int nattribs,
1558 const OSLUStringRep *names,
1559 const TypeDesc *types,
1560 const void **data)
1561{
1562 return false;
1563}
1564
1566 OSL::ShaderGlobals *sg,
1567 const OSL::Vec3 &P,
1568 const OSL::Vec3 &dPdx,
1569 const OSL::Vec3 &dPdy,
1570 const OSL::Vec3 &R,
1571 const OSL::Vec3 &dRdx,
1572 const OSL::Vec3 &dRdy)
1573{
1574 /* todo: options.shader support, maybe options.traceset */
1575 ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
1576 ShaderData *sd = globals->sd;
1577 const ThreadKernelGlobalsCPU *kg = globals->kg;
1578
1579 if (sd == nullptr) {
1580 return false;
1581 }
1582
1583 /* setup ray */
1584 Ray ray;
1585
1586 ray.P = make_float3(P.x, P.y, P.z);
1587 ray.D = make_float3(R.x, R.y, R.z);
1588 ray.tmin = 0.0f;
1589 ray.tmax = (options.maxdist == 1.0e30f) ? FLT_MAX : options.maxdist - options.mindist;
1590 ray.time = sd->time;
1591 ray.self.object = OBJECT_NONE;
1592 ray.self.prim = PRIM_NONE;
1595
1596 if (options.mindist == 0.0f) {
1597 /* avoid self-intersections */
1598 if (ray.P == sd->P) {
1599 ray.self.object = sd->object;
1600 ray.self.prim = sd->prim;
1601 }
1602 }
1603 else {
1604 /* offset for minimum distance */
1605 ray.P += options.mindist * ray.D;
1606 }
1607
1608 /* ray differentials */
1609 differential3 dP;
1610 dP.dx = make_float3(dPdx.x, dPdx.y, dPdx.z);
1611 dP.dy = make_float3(dPdy.x, dPdy.y, dPdy.z);
1612 ray.dP = differential_make_compact(dP);
1613 differential3 dD;
1614 dD.dx = make_float3(dRdx.x, dRdx.y, dRdx.z);
1615 dD.dy = make_float3(dRdy.x, dRdy.y, dRdy.z);
1616 ray.dD = differential_make_compact(dD);
1617
1618 /* allocate trace data */
1619 OSLTraceData *tracedata = globals->tracedata;
1620 tracedata->ray = ray;
1621 tracedata->setup = false;
1622 tracedata->init = true;
1623 tracedata->hit = false;
1624
1625 /* Can't ray-trace from shaders like displacement, before BVH exists. */
1626 if (kernel_data.bvh.bvh_layout == BVH_LAYOUT_NONE) {
1627 return false;
1628 }
1629
1630 /* Ray-trace, leaving out shadow opaque to avoid early exit. */
1632 tracedata->hit = scene_intersect(kg, &ray, visibility, &tracedata->isect);
1633 return tracedata->hit;
1634}
1635
1636bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg,
1637 OSLUStringHash source,
1638 OSLUStringHash name,
1639 const TypeDesc type,
1640 void *val,
1641 bool derivatives)
1642{
1643 ShaderGlobals *globals = reinterpret_cast<ShaderGlobals *>(sg);
1644 const ThreadKernelGlobalsCPU *kg = globals->kg;
1645 OSLTraceData *tracedata = globals->tracedata;
1646
1647 if (source == u_trace && tracedata->init) {
1648 if (name == u_hit) {
1649 return set_attribute<int>(tracedata->hit, type, derivatives, val);
1650 }
1651 if (tracedata->hit) {
1652 if (name == u_hitdist) {
1653 return set_attribute(tracedata->isect.t, type, derivatives, val);
1654 }
1655
1656 ShaderData *sd = &tracedata->sd;
1657
1658 if (!tracedata->setup) {
1659 /* lazy shader data setup */
1660 shader_setup_from_ray(kg, sd, &tracedata->ray, &tracedata->isect);
1661 tracedata->setup = true;
1662 }
1663
1664 if (name == u_N) {
1665 return set_attribute(sd->N, type, derivatives, val);
1666 }
1667 if (name == u_Ng) {
1668 return set_attribute(sd->Ng, type, derivatives, val);
1669 }
1670 if (name == u_P) {
1671 const differential3 dP = differential_from_compact(sd->Ng, sd->dP);
1672 return set_attribute(sd->P, dP.dx, dP.dy, type, derivatives, val);
1673 }
1674 if (name == u_I) {
1675 const differential3 dI = differential_from_compact(sd->wi, sd->dI);
1676 return set_attribute(sd->wi, dI.dx, dI.dy, type, derivatives, val);
1677 }
1678 if (name == u_u) {
1679 return set_attribute(sd->u, sd->du.dx, sd->du.dy, type, derivatives, val);
1680 }
1681 if (name == u_v) {
1682 return set_attribute(sd->v, sd->dv.dx, sd->dv.dy, type, derivatives, val);
1683 }
1684
1685 return get_attribute(sg, derivatives, u_empty, type, name, val);
1686 }
1687 }
1688
1689 return false;
1690}
1691
unsigned int uint
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btDbvtNode * sort(btDbvtNode *n, btDbvtNode *&r)
Definition btDbvt.cpp:418
static void to_scene_linear(ustring colorspace, T *pixels, const size_t num_pixels, bool is_rgba, bool compress_as_srgb)
bool empty() const
int svm_slot(const int slot_index=0) const
static ustring u_bump_map_normal
Definition services.h:275
static ustring u_path_transmission_depth
Definition services.h:310
static bool get_background_attribute(ShaderGlobals *globals, OSLUStringHash name, const TypeDesc type, bool derivatives, void *val)
Definition services.cpp:876
static ustring u_particle_location
Definition services.h:284
static ImageManager * image_manager
Definition services.h:338
static ustring u_object_alpha
Definition services.h:272
bool get_texture_info(OSLUStringHash filename, TextureHandle *texture_handle, TexturePerthread *texture_thread_info, OSL::ShaderGlobals *sg, const int subimage, OSLUStringHash dataname, const TypeDesc datatype, void *data, OSLUStringHash *errormessage) override
static ustring u_u
Definition services.h:318
static ustring u_sensor_size
Definition services.h:325
bool texture(OSLUStringHash filename, OSL::TextureSystem::TextureHandle *texture_handle, TexturePerthread *texture_thread_info, OSL::TextureOpt &options, OSL::ShaderGlobals *sg, const float s, const float t, const float dsdx, const float dtdx, const float dsdy, const float dtdy, const int nchannels, float *result, float *dresultds, float *dresultdt, OSLUStringHash *errormessage) override
bool get_inverse_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, OSL::TransformationPtr xform, float time) override
Definition services.cpp:190
static ustring u_raster
Definition services.h:268
static ustring u_empty
Definition services.h:320
static ustring u_curve_thickness
Definition services.h:296
int pointcloud_search(OSL::ShaderGlobals *sg, OSLUStringHash filename, const OSL::Vec3 &center, const float radius, const int max_points, bool sort, size_t *out_indices, float *out_distances, int derivs_offset) override
static ustring u_ndc
Definition services.h:269
static ustring u_particle_index
Definition services.h:280
static ustring u_point_position
Definition services.h:301
static ustring u_point_radius
Definition services.h:302
static ustring u_curve_tangent_normal
Definition services.h:298
~OSLRenderServices() override
Definition services.cpp:134
int supports(string_view feature) const override
Definition services.cpp:141
static ustring u_image_resolution
Definition services.h:326
static ustring u_path_diffuse_depth
Definition services.h:307
static bool get_camera_attribute(ShaderGlobals *globals, OSLUStringHash name, TypeDesc type, bool derivatives, void *val)
Definition services.cpp:959
static ustring u_normal_map_normal
Definition services.h:304
static ustring u_index
Definition services.h:264
bool get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, OSL::TransformationPtr xform, float time) override
Definition services.cpp:152
static ustring u_curve_length
Definition services.h:297
static ustring u_aperture_aspect_ratio
Definition services.h:327
static ustring u_hit
Definition services.h:312
static ustring u_material_index
Definition services.h:278
static ustring u_path_ray_depth
Definition services.h:306
static ustring u_point_random
Definition services.h:303
static ustring u_is_smooth
Definition services.h:294
static ustring u_object_location
Definition services.h:270
static ustring u_curve_random
Definition services.h:299
static ustring u_particle_rotation
Definition services.h:285
static ustring u_focal_distance
Definition services.h:330
static ustring u_particle_velocity
Definition services.h:287
static ustring u_particle_angular_velocity
Definition services.h:288
static ustring u_N
Definition services.h:314
int pointcloud_get(OSL::ShaderGlobals *sg, OSLUStringHash filename, size_t *indices, const int count, OSLUStringHash attr_name, const TypeDesc attr_type, void *out_data) override
static ustring u_path_glossy_depth
Definition services.h:308
static ustring u_hitdist
Definition services.h:313
static bool get_object_standard_attribute(ShaderGlobals *globals, OSLUStringHash name, const TypeDesc type, bool derivatives, void *val)
Definition services.cpp:695
static ustring u_geom_dupli_uv
Definition services.h:277
static ustring u_aperture_size
Definition services.h:328
static ustring u_I
Definition services.h:317
static ustring u_geom_undisplaced
Definition services.h:293
OSLTextureHandleMap textures
Definition services.h:336
static ustring u_geom_numpolyvertices
Definition services.h:289
static ustring u_v
Definition services.h:319
static ustring u_world
Definition services.h:265
static ustring u_object_random
Definition services.h:279
static ustring u_path_ray_length
Definition services.h:305
static ustring u_screen
Definition services.h:267
static ustring u_object_is_light
Definition services.h:274
static ustring u_particle_random
Definition services.h:281
static ustring u_camera
Definition services.h:266
static ustring u_particle_age
Definition services.h:282
static ustring u_P
Definition services.h:316
bool pointcloud_write(OSL::ShaderGlobals *sg, OSLUStringHash filename, const OSL::Vec3 &pos, const int nattribs, const OSLUStringRep *names, const TypeDesc *types, const void **data) override
bool environment(OSLUStringHash filename, TextureHandle *texture_handle, TexturePerthread *texture_thread_info, OSL::TextureOpt &options, OSL::ShaderGlobals *sg, const OSL::Vec3 &R, const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy, const int nchannels, float *result, float *dresultds, float *dresultdt, OSLUStringHash *errormessage) override
bool get_array_attribute(OSL::ShaderGlobals *sg, bool derivatives, OSLUStringHash object, const TypeDesc type, OSLUStringHash name, const int index, void *val) override
Definition services.cpp:398
static ustring u_object_index
Definition services.h:273
bool get_attribute(OSL::ShaderGlobals *sg, bool derivatives, OSLUStringHash object, const TypeDesc type, OSLUStringHash name, void *val) override
Definition services.cpp:989
static ustring u_is_point
Definition services.h:300
static ustring u_path_transparent_depth
Definition services.h:309
bool get_userdata(bool derivatives, OSLUStringHash name, const TypeDesc type, OSL::ShaderGlobals *sg, void *val) override
bool trace(TraceOpt &options, OSL::ShaderGlobals *sg, const OSL::Vec3 &P, const OSL::Vec3 &dPdx, const OSL::Vec3 &dPdy, const OSL::Vec3 &R, const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy) override
static ustring u_particle_lifetime
Definition services.h:283
static ustring u_is_curve
Definition services.h:295
static ustring u_object_color
Definition services.h:271
static ustring u_distance
Definition services.h:263
static ustring u_aperture_position
Definition services.h:329
static ustring u_Ng
Definition services.h:315
static ustring u_trace
Definition services.h:311
static ustring u_geom_trianglevertices
Definition services.h:290
bool texture3d(OSLUStringHash filename, TextureHandle *texture_handle, TexturePerthread *texture_thread_info, OSL::TextureOpt &options, OSL::ShaderGlobals *sg, const OSL::Vec3 &P, const OSL::Vec3 &dPdx, const OSL::Vec3 &dPdy, const OSL::Vec3 &dPdz, const int nchannels, float *result, float *dresultds, float *dresultdt, float *dresultdr, OSLUStringHash *errormessage) override
static ustring u_geom_polyvertices
Definition services.h:291
bool getmessage(OSL::ShaderGlobals *sg, OSLUStringHash source, OSLUStringHash name, const TypeDesc type, void *val, bool derivatives) override
static ustring u_particle_size
Definition services.h:286
OSL::TextureSystem::TextureHandle * get_texture_handle(OSL::ustring filename, OSL::ShadingContext *context, const OSL::TextureOpt *options) override
static ustring u_geom_dupli_generated
Definition services.h:276
OSLRenderServices(OSL::TextureSystem *texture_system, const int device_type)
Definition services.cpp:129
bool good(OSL::TextureSystem::TextureHandle *texture_handle) override
static ustring u_geom_name
Definition services.h:292
ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals kg, const int id, float3 P, InterpolationType interp)
ccl_device float4 kernel_tex_image_interp(KernelGlobals kg, const int id, const float x, float y)
ccl_device_inline ProjectionTransform projection_transpose(const ProjectionTransform a)
CCL_NAMESPACE_BEGIN struct Options options
#define kernel_data
#define PRIM_NONE
#define OBJECT_NONE
#define ccl_device_inline
#define ccl_device_template_spec
#define CCL_NAMESPACE_END
@ DEVICE_CPU
@ DEVICE_OPTIX
ccl_device_forceinline float4 make_float4(const float x, const float y, const float z, const float w)
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
ccl_device_forceinline float2 make_float2(const float x, const float y)
ccl_device_forceinline float differential_make_compact(const float dD)
ccl_device_forceinline differential3 differential_from_compact(const float3 D, const float dD)
#define str(s)
ccl_device_inline void triangle_vertices(KernelGlobals kg, const int prim, float3 P[3])
ccl_device_inline float3 triangle_smooth_normal_unnormalized(KernelGlobals kg, const ccl_private ShaderData *sd, const float3 Ng, const int prim, const float u, float v)
static ushort indices[]
uint pos
VecBase< float, 4 > float4
ccl_device_inline float hash_uint2_to_float(const uint kx, const uint ky)
Definition hash.h:148
int count
ccl_device_intersect bool scene_intersect(KernelGlobals kg, const ccl_private Ray *ray, const uint visibility, ccl_private Intersection *isect)
CCL_NAMESPACE_BEGIN ccl_device float2 camera_sample_aperture(ccl_constant KernelCamera *cam, const float2 rand)
ccl_device_inline float3 camera_world_to_ndc(KernelGlobals kg, ccl_private ShaderData *sd, float3 P)
const ccl_global KernelWorkTile * tile
ccl_device Transform primitive_attribute_matrix(KernelGlobals kg, const AttributeDescriptor desc)
ccl_device_inline float3 object_dupli_uv(KernelGlobals kg, const int object)
ccl_device_inline int object_particle_id(KernelGlobals kg, const int object)
ccl_device int shader_pass_id(KernelGlobals kg, const ccl_private ShaderData *sd)
ccl_device_inline Transform object_get_inverse_transform(KernelGlobals kg, const ccl_private ShaderData *sd)
ccl_device float4 particle_rotation(KernelGlobals kg, const int particle)
ccl_device_inline void object_position_transform(KernelGlobals kg, const ccl_private ShaderData *sd, ccl_private float3 *P)
ccl_device float3 particle_location(KernelGlobals kg, const int particle)
ccl_device float particle_lifetime(KernelGlobals kg, const int particle)
ccl_device float particle_age(KernelGlobals kg, const int particle)
ccl_device_inline uint particle_index(KernelGlobals kg, const int particle)
ccl_device_inline float3 object_color(KernelGlobals kg, const int object)
ccl_device_inline Transform object_get_transform(KernelGlobals kg, const ccl_private ShaderData *sd)
ccl_device float3 particle_velocity(KernelGlobals kg, const int particle)
ccl_device_inline float object_alpha(KernelGlobals kg, const int object)
ccl_device float3 particle_angular_velocity(KernelGlobals kg, const int particle)
ccl_device_inline float3 object_dupli_generated(KernelGlobals kg, const int object)
ccl_device_inline float object_pass_id(KernelGlobals kg, const int object)
ccl_device float particle_size(KernelGlobals kg, const int particle)
ccl_device_inline float3 object_location(KernelGlobals kg, const ccl_private ShaderData *sd)
ccl_device_inline Transform object_fetch_transform_motion_test(KernelGlobals kg, const int object, const float time, ccl_private Transform *itfm)
ccl_device_inline float object_random_number(KernelGlobals kg, const int object)
#define OSL_TEXTURE_HANDLE_TYPE_SVM
#define OSL_TEXTURE_HANDLE_TYPE_IES
#define OSL_TEXTURE_HANDLE_TYPE_AO_OR_BEVEL
@ NODE_AO_INSIDE
@ NODE_AO_GLOBAL_RADIUS
@ NODE_AO_ONLY_LOCAL
@ NODE_ATTR_FLOAT
@ NODE_ATTR_FLOAT3
@ NODE_ATTR_RGBA
@ NODE_ATTR_FLOAT2
@ NODE_ATTR_FLOAT4
@ NODE_ATTR_MATRIX
@ PRIMITIVE_LAMP
@ PRIMITIVE_MOTION
@ PRIMITIVE_CURVE
@ PRIMITIVE_TRIANGLE
@ PRIMITIVE_POINT
@ ATTR_STD_NOT_FOUND
@ PATH_RAY_SHADOW
@ PATH_RAY_SHADOW_OPAQUE
@ PATH_RAY_EMISSION
@ PATH_RAY_ALL_VISIBILITY
@ PATH_RAY_CAMERA
@ SHADER_SMOOTH_NORMAL
@ SD_OBJECT_TRANSFORM_APPLIED
@ BVH_LAYOUT_NONE
@ CAMERA_ORTHOGRAPHIC
ccl_device_inline float kernel_ies_interp(KernelGlobals kg, const int slot, const float h_angle, const float v_angle)
#define VLOG_INFO
Definition log.h:71
static char ** types
Definition makesdna.cc:71
ccl_device_inline T make_zero()
ccl_device_inline float average(const float2 a)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:15
static ulong state[N]
#define N
#define T
#define R
ccl_device_inline void motion_triangle_vertices(KernelGlobals kg, const int object, const uint3 tri_vindex, const int numsteps, const int numverts, const int step, const float t, float3 verts[3])
OSL::ustringhash OSLUStringHash
Definition osl/compat.h:11
OSL::ustringrep OSLUStringRep
Definition osl/compat.h:15
static OSL::ustring to_ustring(OSLUStringHash h)
Definition osl/compat.h:18
static constexpr TypeDesc TypeFloatArray4(TypeDesc::FLOAT, TypeDesc::SCALAR, TypeDesc::NOSEMANTICS, 4)
CCL_NAMESPACE_BEGIN ccl_device_forceinline T primitive_surface_attribute(KernelGlobals kg, const ccl_private ShaderData *sd, const AttributeDescriptor desc, ccl_private T *dfdx, ccl_private T *dfdy)
Definition primitive.h:32
bool get_object_attribute_impl(const ThreadKernelGlobalsCPU *kg, ShaderData *sd, const AttributeDescriptor &desc, const TypeDesc &type, bool derivatives, void *val)
Definition services.cpp:646
void set_data_float(const float v, const float dx, const float dy, bool derivatives, void *val)
Definition services.cpp:413
bool set_attribute(const T v, const T dx, const T dy, TypeDesc type, bool derivatives, void *val)
static bool get_object_attribute(const ThreadKernelGlobalsCPU *kg, ShaderData *sd, const AttributeDescriptor &desc, const TypeDesc &type, bool derivatives, void *val)
Definition services.cpp:669
void set_data_float4(const float4 v, const float4 dx, const float4 dy, bool derivatives, void *val)
Definition services.cpp:441
static bool set_attribute_float3_3(const float3 P[3], TypeDesc type, bool derivatives, void *val)
Definition services.cpp:605
void set_data_float3(const float3 v, const float3 dx, const float3 dy, bool derivatives, void *val)
Definition services.cpp:424
#define READ_PATH_STATE(elem)
static bool set_attribute_matrix(const Transform &tfm, const TypeDesc type, void *val)
Definition services.cpp:635
static CCL_NAMESPACE_BEGIN void copy_matrix(OSL::Matrix44 &m, const Transform &tfm)
Definition services.cpp:48
long long TypeDesc
CCL_NAMESPACE_BEGIN ccl_device bool attribute_bump_map_normal(KernelGlobals kg, ccl_private const ShaderData *sd, float3 f[3])
ccl_device_inline void shader_setup_from_ray(KernelGlobals kg, ccl_private ShaderData *ccl_restrict sd, const ccl_private Ray *ccl_restrict ray, const ccl_private Intersection *ccl_restrict isect)
Definition shader_data.h:39
#define FLT_MAX
Definition stdcycles.h:14
static bool find_attribute(const std::string &attributes, const char *search_attribute)
NodeAttributeType type
ColorSpaceProcessor * processor
Definition services.h:64
OSL::TextureSystem::TextureHandle * oiio_handle
Definition services.h:63
vector< int4 > svm_slots
Definition services.h:62
float tmax
float tmin
float dD
float3 P
float time
float dP
RaySelfPrimitives self
float3 D
ccl_private ShaderData * sd
const ThreadKernelGlobalsCPU * kg
ccl_private OSLTraceData * tracedata
const struct IntegratorStateCPU * path_state
const struct IntegratorShadowStateCPU * shadow_path_state
packed_float3 N
float x
float y
float z
Definition sky_float3.h:27
float y
Definition sky_float3.h:27
float x
Definition sky_float3.h:27
i
Definition text_draw.cc:230
@ INTERPOLATION_NONE
@ TEX_IMAGE_MISSING_G
@ TEX_IMAGE_MISSING_A
@ TEX_IMAGE_MISSING_R
@ TEX_IMAGE_MISSING_B