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