Blender V4.5
kernel/device/optix/bvh.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5/* OptiX implementation of ray-scene intersection. */
6
7#pragma once
8
9#include "kernel/bvh/types.h"
10#include "kernel/bvh/util.h"
11
12#define OPTIX_DEFINE_ABI_VERSION_ONLY
13#include <optix_function_table.h>
14
16
17/* Utilities. */
18
20{
21 return pointer_unpack_from_uint<T>(optixGetPayload_0(), optixGetPayload_1());
22}
24{
25 return pointer_unpack_from_uint<T>(optixGetPayload_2(), optixGetPayload_3());
26}
27
29{
30 return (T *)(((uint64_t)optixGetPayload_7() << 32) | optixGetPayload_6());
31}
32
34{
35#ifdef __OBJECT_MOTION__
36 /* Always get the instance ID from the TLAS
37 * There might be a motion transform node between TLAS and BLAS which does not have one. */
38 return optixGetInstanceIdFromHandle(optixGetTransformListHandle(0));
39#else
40 return optixGetInstanceId();
41#endif
42}
43
44/* Hit/miss functions. */
45
46extern "C" __global__ void __miss__kernel_optix_miss()
47{
48 /* 'kernel_path_lamp_emission' checks intersection distance, so need to set it even on a miss. */
49 optixSetPayload_0(__float_as_uint(optixGetRayTmax()));
50 optixSetPayload_5(PRIMITIVE_NONE);
51}
52
53extern "C" __global__ void __anyhit__kernel_optix_ignore()
54{
55 return optixIgnoreIntersection();
56}
57
58extern "C" __global__ void __closesthit__kernel_optix_ignore() {}
59
60extern "C" __global__ void __anyhit__kernel_optix_local_hit()
61{
62#if defined(__HAIR__) || defined(__POINTCLOUD__)
63 if (!optixIsTriangleHit()) {
64 /* Ignore curves and points. */
65 return optixIgnoreIntersection();
66 }
67#endif
68
69#ifdef __BVH_LOCAL__
70 const int object = get_object_id();
71 if (object != optixGetPayload_4() /* local_object */) {
72 /* Only intersect with matching object. */
73 return optixIgnoreIntersection();
74 }
75
76 const int prim = optixGetPrimitiveIndex();
78 if (intersection_skip_self_local(ray->self, prim)) {
79 return optixIgnoreIntersection();
80 }
81
82 const uint max_hits = optixGetPayload_5();
83 if (max_hits == 0) {
84 /* Special case for when no hit information is requested, just report that something was hit */
85 optixSetPayload_5(true);
86 return optixTerminateRay();
87 }
88
89 int hit = 0;
90 uint *const lcg_state = get_payload_ptr_0<uint>();
92
93 if (lcg_state) {
94 for (int i = min(max_hits, local_isect->num_hits) - 1; i >= 0; --i) {
95 if (optixGetRayTmax() == local_isect->hits[i].t) {
96 return optixIgnoreIntersection();
97 }
98 }
99
100 hit = local_isect->num_hits++;
101
102 if (local_isect->num_hits > max_hits) {
103 hit = lcg_step_uint(lcg_state) % local_isect->num_hits;
104 if (hit >= max_hits) {
105 return optixIgnoreIntersection();
106 }
107 }
108 }
109 else {
110 if (local_isect->num_hits && optixGetRayTmax() > local_isect->hits[0].t) {
111 /* Record closest intersection only.
112 * Do not terminate ray here, since there is no guarantee about distance ordering in any-hit.
113 */
114 return optixIgnoreIntersection();
115 }
116
117 local_isect->num_hits = 1;
118 }
119
120 Intersection *isect = &local_isect->hits[hit];
121 isect->t = optixGetRayTmax();
122 isect->prim = prim;
123 isect->object = get_object_id();
124 isect->type = kernel_data_fetch(objects, isect->object).primitive_type;
125
126 const float2 barycentrics = optixGetTriangleBarycentrics();
127 isect->u = barycentrics.x;
128 isect->v = barycentrics.y;
129
130 /* Record geometric normal. */
131 const packed_uint3 tri_vindex = kernel_data_fetch(tri_vindex, prim);
132 const float3 tri_a = kernel_data_fetch(tri_verts, tri_vindex.x);
133 const float3 tri_b = kernel_data_fetch(tri_verts, tri_vindex.y);
134 const float3 tri_c = kernel_data_fetch(tri_verts, tri_vindex.z);
135
136 local_isect->Ng[hit] = normalize(cross(tri_b - tri_a, tri_c - tri_a));
137
138 /* Continue tracing (without this the trace call would return after the first hit). */
139 optixIgnoreIntersection();
140#endif
141}
142
143extern "C" __global__ void __anyhit__kernel_optix_shadow_all_hit()
144{
145#ifdef __SHADOW_RECORD_ALL__
146 int prim = optixGetPrimitiveIndex();
147 const uint object = get_object_id();
148# ifdef __VISIBILITY_FLAG__
149 const uint visibility = optixGetPayload_4();
150 if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
151 return optixIgnoreIntersection();
152 }
153# endif
154
155 float u = 0.0f, v = 0.0f;
156 int type = 0;
157 if (optixIsTriangleHit()) {
158 /* Triangle. */
159 const float2 barycentrics = optixGetTriangleBarycentrics();
160 u = barycentrics.x;
161 v = barycentrics.y;
162 type = kernel_data_fetch(objects, object).primitive_type;
163 }
164# ifdef __HAIR__
165 else if ((optixGetHitKind() & (~PRIMITIVE_MOTION)) != PRIMITIVE_POINT) {
166 /* Curve. */
167 u = __uint_as_float(optixGetAttribute_0());
168 v = __uint_as_float(optixGetAttribute_1());
169
170 const KernelCurveSegment segment = kernel_data_fetch(curve_segments, prim);
171 type = segment.type;
172 prim = segment.prim;
173
174# if OPTIX_ABI_VERSION < 55
175 /* Filter out curve end-caps. */
176 if (u == 0.0f || u == 1.0f) {
177 return optixIgnoreIntersection();
178 }
179# endif
180 }
181# endif
182 else {
183 /* Point. */
184 type = kernel_data_fetch(objects, object).primitive_type;
185 u = 0.0f;
186 v = 0.0f;
187 }
188
190 if (intersection_skip_self_shadow(ray->self, object, prim)) {
191 return optixIgnoreIntersection();
192 }
193
194# ifdef __SHADOW_LINKING__
195 if (intersection_skip_shadow_link(nullptr, ray->self, object)) {
196 return optixIgnoreIntersection();
197 }
198# endif
199
200# ifndef __TRANSPARENT_SHADOWS__
201 /* No transparent shadows support compiled in, make opaque. */
202 optixSetPayload_5(true);
203 return optixTerminateRay();
204# else
205 const uint max_hits = optixGetPayload_3();
206 const uint num_hits_packed = optixGetPayload_2();
207 const uint num_recorded_hits = uint16_unpack_from_uint_0(num_hits_packed);
208 const uint num_hits = uint16_unpack_from_uint_1(num_hits_packed);
209
210 /* If no transparent shadows, all light is blocked and we can stop immediately. */
211 if (num_hits >= max_hits ||
213 {
214 optixSetPayload_5(true);
215 return optixTerminateRay();
216 }
217
218 /* Always use baked shadow transparency for curves. */
219 if (type & PRIMITIVE_CURVE) {
220 float throughput = __uint_as_float(optixGetPayload_1());
221 throughput *= intersection_curve_shadow_transparency(nullptr, object, prim, type, u);
222 optixSetPayload_1(__float_as_uint(throughput));
223 optixSetPayload_2(uint16_pack_to_uint(num_recorded_hits, num_hits + 1));
224
225 if (throughput < CURVE_SHADOW_TRANSPARENCY_CUTOFF) {
226 optixSetPayload_5(true);
227 return optixTerminateRay();
228 }
229 else {
230 /* Continue tracing. */
231 optixIgnoreIntersection();
232 return;
233 }
234 }
235
236 /* Record transparent intersection. */
237 optixSetPayload_2(uint16_pack_to_uint(num_recorded_hits + 1, num_hits + 1));
238
239 uint record_index = num_recorded_hits;
240
241 const IntegratorShadowState state = optixGetPayload_0();
242
243 const uint max_record_hits = min(max_hits, INTEGRATOR_SHADOW_ISECT_SIZE);
244 if (record_index >= max_record_hits) {
245 /* If maximum number of hits reached, find a hit to replace. */
246 float max_recorded_t = INTEGRATOR_STATE_ARRAY(state, shadow_isect, 0, t);
247 uint max_recorded_hit = 0;
248
249 for (int i = 1; i < max_record_hits; i++) {
250 const float isect_t = INTEGRATOR_STATE_ARRAY(state, shadow_isect, i, t);
251 if (isect_t > max_recorded_t) {
252 max_recorded_t = isect_t;
253 max_recorded_hit = i;
254 }
255 }
256
257 if (optixGetRayTmax() >= max_recorded_t) {
258 /* Accept hit, so that OptiX won't consider any more hits beyond the distance of the
259 * current hit anymore. */
260 return;
261 }
262
263 record_index = max_recorded_hit;
264 }
265
266 INTEGRATOR_STATE_ARRAY_WRITE(state, shadow_isect, record_index, u) = u;
267 INTEGRATOR_STATE_ARRAY_WRITE(state, shadow_isect, record_index, v) = v;
268 INTEGRATOR_STATE_ARRAY_WRITE(state, shadow_isect, record_index, t) = optixGetRayTmax();
269 INTEGRATOR_STATE_ARRAY_WRITE(state, shadow_isect, record_index, prim) = prim;
270 INTEGRATOR_STATE_ARRAY_WRITE(state, shadow_isect, record_index, object) = object;
271 INTEGRATOR_STATE_ARRAY_WRITE(state, shadow_isect, record_index, type) = type;
272
273 /* Continue tracing. */
274 optixIgnoreIntersection();
275# endif /* __TRANSPARENT_SHADOWS__ */
276#endif /* __SHADOW_RECORD_ALL__ */
277}
278
279extern "C" __global__ void __anyhit__kernel_optix_volume_test()
280{
281#if defined(__HAIR__) || defined(__POINTCLOUD__)
282 if (!optixIsTriangleHit()) {
283 /* Ignore curves. */
284 return optixIgnoreIntersection();
285 }
286#endif
287
288 const uint object = get_object_id();
289#ifdef __VISIBILITY_FLAG__
290 const uint visibility = optixGetPayload_4();
291 if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
292 return optixIgnoreIntersection();
293 }
294#endif
295
296 if ((kernel_data_fetch(object_flag, object) & SD_OBJECT_HAS_VOLUME) == 0) {
297 return optixIgnoreIntersection();
298 }
299
300 const int prim = optixGetPrimitiveIndex();
302 if (intersection_skip_self(ray->self, object, prim)) {
303 return optixIgnoreIntersection();
304 }
305}
306
307extern "C" __global__ void __anyhit__kernel_optix_visibility_test()
308{
309#ifdef __HAIR__
310# if OPTIX_ABI_VERSION < 55
311 if (optixGetPrimitiveType() == OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BSPLINE) {
312 /* Filter out curve end-caps. */
313 const float u = __uint_as_float(optixGetAttribute_0());
314 if (u == 0.0f || u == 1.0f) {
315 return optixIgnoreIntersection();
316 }
317 }
318# endif
319#endif
320
321 const uint object = get_object_id();
322 const uint visibility = optixGetPayload_4();
323#ifdef __VISIBILITY_FLAG__
324 if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
325 return optixIgnoreIntersection();
326 }
327#endif
328
329 int prim = optixGetPrimitiveIndex();
330 if (optixIsTriangleHit()) {
331 /* Triangle. */
332 }
333#ifdef __HAIR__
334 else if ((optixGetHitKind() & (~PRIMITIVE_MOTION)) != PRIMITIVE_POINT) {
335 /* Curve. */
336 prim = kernel_data_fetch(curve_segments, prim).prim;
337 }
338#endif
339
341
342 if (visibility & PATH_RAY_SHADOW_OPAQUE) {
343#ifdef __SHADOW_LINKING__
344 if (intersection_skip_shadow_link(nullptr, ray->self, object)) {
345 return optixIgnoreIntersection();
346 }
347#endif
348
349 if (intersection_skip_self_shadow(ray->self, object, prim)) {
350 return optixIgnoreIntersection();
351 }
352 else {
353 /* Shadow ray early termination. */
354 return optixTerminateRay();
355 }
356 }
357 else {
358 if (intersection_skip_self(ray->self, object, prim)) {
359 return optixIgnoreIntersection();
360 }
361 }
362}
363
364extern "C" __global__ void __closesthit__kernel_optix_hit()
365{
366 const int object = get_object_id();
367 const int prim = optixGetPrimitiveIndex();
368
369 optixSetPayload_0(__float_as_uint(optixGetRayTmax())); /* Intersection distance */
370 optixSetPayload_4(object);
371
372 if (optixIsTriangleHit()) {
373 const float2 barycentrics = optixGetTriangleBarycentrics();
374 optixSetPayload_1(__float_as_uint(barycentrics.x));
375 optixSetPayload_2(__float_as_uint(barycentrics.y));
376 optixSetPayload_3(prim);
377 optixSetPayload_5(kernel_data_fetch(objects, object).primitive_type);
378 }
379 else if ((optixGetHitKind() & (~PRIMITIVE_MOTION)) != PRIMITIVE_POINT) {
380 const KernelCurveSegment segment = kernel_data_fetch(curve_segments, prim);
381 optixSetPayload_1(optixGetAttribute_0()); /* Same as 'optixGetCurveParameter()' */
382 optixSetPayload_2(optixGetAttribute_1());
383 optixSetPayload_3(segment.prim);
384 optixSetPayload_5(segment.type);
385 }
386 else {
387 optixSetPayload_1(0);
388 optixSetPayload_2(0);
389 optixSetPayload_3(prim);
390 optixSetPayload_5(kernel_data_fetch(objects, object).primitive_type);
391 }
392}
393
394/* Custom primitive intersection functions. */
395
396#ifdef __HAIR__
397ccl_device_inline void optix_intersection_curve(const int prim, const int type)
398{
399 const int object = get_object_id();
400
401# ifdef __VISIBILITY_FLAG__
402 const uint visibility = optixGetPayload_4();
403 if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
404 return;
405 }
406# endif
407
408 const float3 ray_P = optixGetObjectRayOrigin();
409 const float3 ray_D = optixGetObjectRayDirection();
410 const float ray_tmin = optixGetRayTmin();
411
412# ifdef __OBJECT_MOTION__
413 const float time = optixGetRayTime();
414# else
415 const float time = 0.0f;
416# endif
417
418 Intersection isect;
419 isect.t = optixGetRayTmax();
420
421 if (curve_intersect(nullptr, &isect, ray_P, ray_D, ray_tmin, isect.t, object, prim, time, type))
422 {
423 static_assert(PRIMITIVE_ALL < 128, "Values >= 128 are reserved for OptiX internal use");
424 optixReportIntersection(isect.t,
425 type & PRIMITIVE_ALL,
426 __float_as_int(isect.u), /* Attribute_0 */
427 __float_as_int(isect.v)); /* Attribute_1 */
428 }
429}
430
431extern "C" __global__ void __intersection__curve_ribbon()
432{
433 const KernelCurveSegment segment = kernel_data_fetch(curve_segments, optixGetPrimitiveIndex());
434 const int prim = segment.prim;
435 const int type = segment.type;
436 if (type & PRIMITIVE_CURVE_RIBBON) {
437 optix_intersection_curve(prim, type);
438 }
439}
440
441#endif
442
443#ifdef __POINTCLOUD__
444extern "C" __global__ void __intersection__point()
445{
446 const int prim = optixGetPrimitiveIndex();
447 const int object = get_object_id();
448 const int type = kernel_data_fetch(objects, object).primitive_type;
449
450# ifdef __VISIBILITY_FLAG__
451 const uint visibility = optixGetPayload_4();
452 if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
453 return;
454 }
455# endif
456
457 const float3 ray_P = optixGetObjectRayOrigin();
458 const float3 ray_D = optixGetObjectRayDirection();
459 const float ray_tmin = optixGetRayTmin();
460
461# ifdef __OBJECT_MOTION__
462 const float time = optixGetRayTime();
463# else
464 const float time = 0.0f;
465# endif
466
467 Intersection isect;
468 isect.t = optixGetRayTmax();
469
470 if (point_intersect(nullptr, &isect, ray_P, ray_D, ray_tmin, isect.t, object, prim, time, type))
471 {
472 static_assert(PRIMITIVE_ALL < 128, "Values >= 128 are reserved for OptiX internal use");
473 optixReportIntersection(isect.t, type & PRIMITIVE_ALL);
474 }
475}
476#endif
477
478/* Scene intersection. */
479
481 const ccl_private Ray *ray,
482 const uint visibility,
484{
485 uint p0 = 0;
486 uint p1 = 0;
487 uint p2 = 0;
488 uint p3 = 0;
489 uint p4 = visibility;
490 uint p5 = PRIMITIVE_NONE;
493
494 uint ray_mask = visibility & 0xFF;
495 uint ray_flags = OPTIX_RAY_FLAG_ENFORCE_ANYHIT;
496 if (0 == ray_mask && (visibility & ~0xFF) != 0) {
497 ray_mask = 0xFF;
498 }
499 else if (visibility & PATH_RAY_SHADOW_OPAQUE) {
500 ray_flags |= OPTIX_RAY_FLAG_TERMINATE_ON_FIRST_HIT;
501 }
502
503 optixTrace(intersection_ray_valid(ray) ? kernel_data.device_bvh : 0,
504 ray->P,
505 ray->D,
506 ray->tmin,
507 ray->tmax,
508 ray->time,
509 ray_mask,
510 ray_flags,
511 0, /* SBT offset for PG_HITD */
512 0,
513 0,
514 p0,
515 p1,
516 p2,
517 p3,
518 p4,
519 p5,
520 p6,
521 p7);
522
523 isect->t = __uint_as_float(p0);
524 isect->u = __uint_as_float(p1);
525 isect->v = __uint_as_float(p2);
526 isect->prim = p3;
527 isect->object = p4;
528 isect->type = p5;
529
530 return p5 != PRIMITIVE_NONE;
531}
532
534 const ccl_private Ray *ray,
535 const uint visibility)
536{
537 uint p0 = 0;
538 uint p1 = 0;
539 uint p2 = 0;
540 uint p3 = 0;
541 uint p4 = visibility;
542 uint p5 = PRIMITIVE_NONE;
545
546 uint ray_mask = visibility & 0xFF;
547 uint ray_flags = OPTIX_RAY_FLAG_ENFORCE_ANYHIT;
548 if (0 == ray_mask && (visibility & ~0xFF) != 0) {
549 ray_mask = 0xFF;
550 }
551 else if (visibility & PATH_RAY_SHADOW_OPAQUE) {
552 ray_flags |= OPTIX_RAY_FLAG_TERMINATE_ON_FIRST_HIT;
553 }
554
555 optixTraverse(intersection_ray_valid(ray) ? kernel_data.device_bvh : 0,
556 ray->P,
557 ray->D,
558 ray->tmin,
559 ray->tmax,
560 ray->time,
561 ray_mask,
562 ray_flags,
563 0, /* SBT offset for PG_HITD */
564 0,
565 0,
566 p0,
567 p1,
568 p2,
569 p3,
570 p4,
571 p5,
572 p6,
573 p7);
574
575 return optixHitObjectIsHit();
576}
577
578#ifdef __BVH_LOCAL__
579template<bool single_hit = false>
580ccl_device_intersect bool scene_intersect_local(KernelGlobals kg,
581 const ccl_private Ray *ray,
582 ccl_private LocalIntersection *local_isect,
583 const int local_object,
584 ccl_private uint *lcg_state,
585 const int max_hits)
586{
587 uint p0 = pointer_pack_to_uint_0(lcg_state);
588 uint p1 = pointer_pack_to_uint_1(lcg_state);
589 uint p2 = pointer_pack_to_uint_0(local_isect);
590 uint p3 = pointer_pack_to_uint_1(local_isect);
591 uint p4 = local_object;
594
595 /* Is set to zero on miss or if ray is aborted, so can be used as return value. */
596 uint p5 = max_hits;
597
598 if (local_isect) {
599 local_isect->num_hits = 0; /* Initialize hit count to zero. */
600 }
601 optixTraverse(intersection_ray_valid(ray) ? kernel_data.device_bvh : 0,
602 ray->P,
603 ray->D,
604 ray->tmin,
605 ray->tmax,
606 ray->time,
607 0xFF,
608 /* Need to always call into __anyhit__kernel_optix_local_hit. */
609 OPTIX_RAY_FLAG_ENFORCE_ANYHIT,
610 2, /* SBT offset for PG_HITL */
611 0,
612 0,
613 p0,
614 p1,
615 p2,
616 p3,
617 p4,
618 p5,
619 p6,
620 p7);
621
622 return p5;
623}
624#endif
625
626#ifdef __SHADOW_RECORD_ALL__
627ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals kg,
629 const ccl_private Ray *ray,
630 const uint visibility,
631 const uint max_hits,
632 ccl_private uint *num_recorded_hits,
633 ccl_private float *throughput)
634{
635 uint p0 = state;
636 uint p1 = __float_as_uint(1.0f); /* Throughput. */
637 uint p2 = 0; /* Number of hits. */
638 uint p3 = max_hits;
639 uint p4 = visibility;
640 uint p5 = false;
643
644 uint ray_mask = visibility & 0xFF;
645 if (0 == ray_mask && (visibility & ~0xFF) != 0) {
646 ray_mask = 0xFF;
647 }
648
649 optixTraverse(intersection_ray_valid(ray) ? kernel_data.device_bvh : 0,
650 ray->P,
651 ray->D,
652 ray->tmin,
653 ray->tmax,
654 ray->time,
655 ray_mask,
656 /* Need to always call into __anyhit__kernel_optix_shadow_all_hit. */
657 OPTIX_RAY_FLAG_ENFORCE_ANYHIT,
658 1, /* SBT offset for PG_HITS */
659 0,
660 0,
661 p0,
662 p1,
663 p2,
664 p3,
665 p4,
666 p5,
667 p6,
668 p7);
669
670 *num_recorded_hits = uint16_unpack_from_uint_0(p2);
671 *throughput = __uint_as_float(p1);
672
673 return p5;
674}
675#endif
676
677#ifdef __VOLUME__
678ccl_device_intersect bool scene_intersect_volume(KernelGlobals kg,
679 const ccl_private Ray *ray,
681 const uint visibility)
682{
683 uint p0 = 0;
684 uint p1 = 0;
685 uint p2 = 0;
686 uint p3 = 0;
687 uint p4 = visibility;
688 uint p5 = PRIMITIVE_NONE;
691
692 uint ray_mask = visibility & 0xFF;
693 if (0 == ray_mask && (visibility & ~0xFF) != 0) {
694 ray_mask = 0xFF;
695 }
696
697 optixTrace(intersection_ray_valid(ray) ? kernel_data.device_bvh : 0,
698 ray->P,
699 ray->D,
700 ray->tmin,
701 ray->tmax,
702 ray->time,
703 ray_mask,
704 /* Need to always call into __anyhit__kernel_optix_volume_test. */
705 OPTIX_RAY_FLAG_ENFORCE_ANYHIT,
706 3, /* SBT offset for PG_HITV */
707 0,
708 0,
709 p0,
710 p1,
711 p2,
712 p3,
713 p4,
714 p5,
715 p6,
716 p7);
717
718 isect->t = __uint_as_float(p0);
719 isect->u = __uint_as_float(p1);
720 isect->v = __uint_as_float(p2);
721 isect->prim = p3;
722 isect->object = p4;
723 isect->type = p5;
724
725 return p5 != PRIMITIVE_NONE;
726}
727#endif
728
unsigned int uint
ATTR_WARN_UNUSED_RESULT const BMVert * v
unsigned long long int uint64_t
ccl_device_forceinline int intersection_get_shader_flags(KernelGlobals kg, const int prim, const int type)
ccl_device_inline bool intersection_skip_shadow_link(KernelGlobals kg, const ccl_ray_data RaySelfPrimitives &self, const int isect_object)
ccl_device_inline bool intersection_skip_self_shadow(const ccl_ray_data RaySelfPrimitives &self, const int object, const int prim)
ccl_device_inline bool intersection_skip_self(const ccl_ray_data RaySelfPrimitives &self, const int object, const int prim)
CCL_NAMESPACE_BEGIN ccl_device_inline bool intersection_ray_valid(const ccl_private Ray *ray)
#define CURVE_SHADOW_TRANSPARENCY_CUTOFF
ccl_device_inline float intersection_curve_shadow_transparency(KernelGlobals kg, const int object, const int prim, const int type, const float u)
ccl_device_inline bool intersection_skip_self_local(const ccl_ray_data RaySelfPrimitives &self, const int prim)
#define kernel_data
#define ccl_device_forceinline
#define kernel_data_fetch(name, index)
#define INTEGRATOR_SHADOW_ISECT_SIZE
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define CCL_NAMESPACE_END
#define __float_as_int(x)
#define __float_as_uint(x)
#define __uint_as_float(x)
VecBase< float, D > normalize(VecOp< float, D >) RET
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
#define ccl_device_intersect
ccl_device_forceinline T * get_payload_ptr_6()
__global__ void __anyhit__kernel_optix_volume_test()
__global__ void __miss__kernel_optix_miss()
__global__ void __anyhit__kernel_optix_visibility_test()
__global__ void __closesthit__kernel_optix_ignore()
__global__ void __anyhit__kernel_optix_local_hit()
__global__ void __anyhit__kernel_optix_shadow_all_hit()
__global__ void __closesthit__kernel_optix_hit()
__global__ void __anyhit__kernel_optix_ignore()
ccl_device_forceinline T * get_payload_ptr_2()
CCL_NAMESPACE_BEGIN ccl_device_forceinline T * get_payload_ptr_0()
ccl_device_intersect bool scene_intersect(KernelGlobals kg, const ccl_private Ray *ray, const uint visibility, ccl_private Intersection *isect)
ccl_device_intersect bool scene_intersect_shadow(KernelGlobals kg, const ccl_private Ray *ray, const uint visibility)
ccl_device_forceinline int get_object_id()
@ SD_HAS_TRANSPARENT_SHADOW
@ PRIMITIVE_ALL
@ PRIMITIVE_MOTION
@ PRIMITIVE_NONE
@ PRIMITIVE_CURVE_RIBBON
@ PRIMITIVE_CURVE
@ PRIMITIVE_POINT
@ PATH_RAY_SHADOW_OPAQUE
@ SD_OBJECT_HAS_VOLUME
CCL_NAMESPACE_BEGIN ccl_device uint lcg_step_uint(T rng)
Definition lcg.h:14
ccl_device_inline uint uint16_unpack_from_uint_1(const uint i)
Definition math_base.h:336
ccl_device_inline uint pointer_pack_to_uint_1(T *ptr)
Definition math_base.h:316
ccl_device_inline uint uint16_pack_to_uint(const uint a, const uint b)
Definition math_base.h:326
ccl_device_inline uint pointer_pack_to_uint_0(T *ptr)
Definition math_base.h:311
ccl_device_inline T * pointer_unpack_from_uint(const uint a, const uint b)
Definition math_base.h:321
ccl_device_inline uint uint16_unpack_from_uint_0(const uint i)
Definition math_base.h:331
static ulong state[N]
#define T
Segment< FEdge *, Vec3r > segment
#define min(a, b)
Definition sort.cc:36
IntegratorShadowStateCPU * IntegratorShadowState
Definition state.h:230
#define INTEGRATOR_STATE_ARRAY_WRITE(state, nested_struct, array_index, member)
Definition state.h:240
#define INTEGRATOR_STATE_ARRAY(state, nested_struct, array_index, member)
Definition state.h:238
struct Intersection hits[LOCAL_MAX_HITS]
float3 Ng[LOCAL_MAX_HITS]
float x
float y
i
Definition text_draw.cc:230