Blender V5.0
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# endif
175 else {
176 /* Point. */
177 type = kernel_data_fetch(objects, object).primitive_type;
178 u = 0.0f;
179 v = 0.0f;
180 }
181
183 if (intersection_skip_self_shadow(ray->self, object, prim)) {
184 return optixIgnoreIntersection();
185 }
186
187# ifdef __SHADOW_LINKING__
188 if (intersection_skip_shadow_link(nullptr, ray->self, object)) {
189 return optixIgnoreIntersection();
190 }
191# endif
192
193# ifndef __TRANSPARENT_SHADOWS__
194 /* No transparent shadows support compiled in, make opaque. */
195 optixSetPayload_5(true);
196 return optixTerminateRay();
197# else
198 const uint max_transparent_hits = optixGetPayload_3();
199 const uint num_hits_packed = optixGetPayload_2();
200 const uint num_recorded_hits = uint16_unpack_from_uint_0(num_hits_packed);
201 uint num_transparent_hits = uint16_unpack_from_uint_1(num_hits_packed);
202
203 /* If no transparent shadows, all light is blocked and we can stop immediately. */
204 const int flags = intersection_get_shader_flags(nullptr, prim, type);
205 if (!(flags & SD_HAS_TRANSPARENT_SHADOW)) {
206 optixSetPayload_5(true);
207 return optixTerminateRay();
208 }
209
210 /* Only count transparent bounces, volume bounds bounces are counted during shading. */
211 num_transparent_hits += !(flags & SD_HAS_ONLY_VOLUME);
212 if (num_transparent_hits > max_transparent_hits) {
213 /* Max number of hits exceeded. */
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_transparent_hits));
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_transparent_hits));
238
239 uint record_index = num_recorded_hits;
240
241 const IntegratorShadowState state = optixGetPayload_0();
242
243 const uint max_record_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 const uint object = get_object_id();
310 const uint visibility = optixGetPayload_4();
311#ifdef __VISIBILITY_FLAG__
312 if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
313 return optixIgnoreIntersection();
314 }
315#endif
316
317 int prim = optixGetPrimitiveIndex();
318 if (optixIsTriangleHit()) {
319 /* Triangle. */
320 }
321#ifdef __HAIR__
322 else if ((optixGetHitKind() & (~PRIMITIVE_MOTION)) != PRIMITIVE_POINT) {
323 /* Curve. */
324 prim = kernel_data_fetch(curve_segments, prim).prim;
325 }
326#endif
327
329
330 if (visibility & PATH_RAY_SHADOW_OPAQUE) {
331#ifdef __SHADOW_LINKING__
332 if (intersection_skip_shadow_link(nullptr, ray->self, object)) {
333 return optixIgnoreIntersection();
334 }
335#endif
336
337 if (intersection_skip_self_shadow(ray->self, object, prim)) {
338 return optixIgnoreIntersection();
339 }
340 else {
341 /* Shadow ray early termination. */
342 return optixTerminateRay();
343 }
344 }
345 else {
346 if (intersection_skip_self(ray->self, object, prim)) {
347 return optixIgnoreIntersection();
348 }
349 }
350}
351
352extern "C" __global__ void __closesthit__kernel_optix_hit()
353{
354 const int object = get_object_id();
355 const int prim = optixGetPrimitiveIndex();
356
357 optixSetPayload_0(__float_as_uint(optixGetRayTmax())); /* Intersection distance */
358 optixSetPayload_4(object);
359
360 if (optixIsTriangleHit()) {
361 const float2 barycentrics = optixGetTriangleBarycentrics();
362 optixSetPayload_1(__float_as_uint(barycentrics.x));
363 optixSetPayload_2(__float_as_uint(barycentrics.y));
364 optixSetPayload_3(prim);
365 optixSetPayload_5(kernel_data_fetch(objects, object).primitive_type);
366 }
367 else if ((optixGetHitKind() & (~PRIMITIVE_MOTION)) != PRIMITIVE_POINT) {
368 const KernelCurveSegment segment = kernel_data_fetch(curve_segments, prim);
369 optixSetPayload_1(optixGetAttribute_0()); /* Same as 'optixGetCurveParameter()' */
370 optixSetPayload_2(optixGetAttribute_1());
371 optixSetPayload_3(segment.prim);
372 optixSetPayload_5(segment.type);
373 }
374 else {
375 optixSetPayload_1(0);
376 optixSetPayload_2(0);
377 optixSetPayload_3(prim);
378 optixSetPayload_5(kernel_data_fetch(objects, object).primitive_type);
379 }
380}
381
382/* Custom primitive intersection functions. */
383
384#ifdef __HAIR__
385ccl_device_inline void optix_intersection_curve(const int prim, const int type)
386{
387 const int object = get_object_id();
388
389# ifdef __VISIBILITY_FLAG__
390 const uint visibility = optixGetPayload_4();
391 if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
392 return;
393 }
394# endif
395
396 const float3 ray_P = optixGetObjectRayOrigin();
397 const float3 ray_D = optixGetObjectRayDirection();
398 const float ray_tmin = optixGetRayTmin();
399
400# ifdef __OBJECT_MOTION__
401 const float time = optixGetRayTime();
402# else
403 const float time = 0.0f;
404# endif
405
406 Intersection isect;
407 isect.t = optixGetRayTmax();
408
409 if (curve_intersect(nullptr, &isect, ray_P, ray_D, ray_tmin, isect.t, object, prim, time, type))
410 {
411 static_assert(PRIMITIVE_ALL < 128, "Values >= 128 are reserved for OptiX internal use");
412 optixReportIntersection(isect.t,
413 type & PRIMITIVE_ALL,
414 __float_as_int(isect.u), /* Attribute_0 */
415 __float_as_int(isect.v)); /* Attribute_1 */
416 }
417}
418
419extern "C" __global__ void __intersection__curve_ribbon()
420{
421 const KernelCurveSegment segment = kernel_data_fetch(curve_segments, optixGetPrimitiveIndex());
422 const int prim = segment.prim;
423 const int type = segment.type;
424 if ((type & PRIMITIVE_CURVE) == PRIMITIVE_CURVE_RIBBON) {
425 optix_intersection_curve(prim, type);
426 }
427}
428
429#endif
430
431#ifdef __POINTCLOUD__
432extern "C" __global__ void __intersection__point()
433{
434 const int prim = optixGetPrimitiveIndex();
435 const int object = get_object_id();
436 const int type = kernel_data_fetch(objects, object).primitive_type;
437
438# ifdef __VISIBILITY_FLAG__
439 const uint visibility = optixGetPayload_4();
440 if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
441 return;
442 }
443# endif
444
445 const float3 ray_P = optixGetObjectRayOrigin();
446 const float3 ray_D = optixGetObjectRayDirection();
447 const float ray_tmin = optixGetRayTmin();
448
449# ifdef __OBJECT_MOTION__
450 const float time = optixGetRayTime();
451# else
452 const float time = 0.0f;
453# endif
454
455 Intersection isect;
456 isect.t = optixGetRayTmax();
457
458 if (point_intersect(nullptr, &isect, ray_P, ray_D, ray_tmin, isect.t, object, prim, time, type))
459 {
460 static_assert(PRIMITIVE_ALL < 128, "Values >= 128 are reserved for OptiX internal use");
461 optixReportIntersection(isect.t, type & PRIMITIVE_ALL);
462 }
463}
464#endif
465
466/* Scene intersection. */
467
469 const ccl_private Ray *ray,
470 const uint visibility,
472{
473 uint p0 = 0;
474 uint p1 = 0;
475 uint p2 = 0;
476 uint p3 = 0;
477 uint p4 = visibility;
478 uint p5 = PRIMITIVE_NONE;
481
482 uint ray_mask = visibility & 0xFF;
483 uint ray_flags = OPTIX_RAY_FLAG_ENFORCE_ANYHIT;
484 if (0 == ray_mask && (visibility & ~0xFF) != 0) {
485 ray_mask = 0xFF;
486 }
487 else if (visibility & PATH_RAY_SHADOW_OPAQUE) {
488 ray_flags |= OPTIX_RAY_FLAG_TERMINATE_ON_FIRST_HIT;
489 }
490
491 optixTrace(intersection_ray_valid(ray) ? kernel_data.device_bvh : 0,
492 ray->P,
493 ray->D,
494 ray->tmin,
495 ray->tmax,
496 ray->time,
497 ray_mask,
498 ray_flags,
499 0, /* SBT offset for PG_HITD */
500 0,
501 0,
502 p0,
503 p1,
504 p2,
505 p3,
506 p4,
507 p5,
508 p6,
509 p7);
510
511 isect->t = __uint_as_float(p0);
512 isect->u = __uint_as_float(p1);
513 isect->v = __uint_as_float(p2);
514 isect->prim = p3;
515 isect->object = p4;
516 isect->type = p5;
517
518 return p5 != PRIMITIVE_NONE;
519}
520
522 const ccl_private Ray *ray,
523 const uint visibility)
524{
525 uint p0 = 0;
526 uint p1 = 0;
527 uint p2 = 0;
528 uint p3 = 0;
529 uint p4 = visibility;
530 uint p5 = PRIMITIVE_NONE;
533
534 uint ray_mask = visibility & 0xFF;
535 uint ray_flags = OPTIX_RAY_FLAG_ENFORCE_ANYHIT;
536 if (0 == ray_mask && (visibility & ~0xFF) != 0) {
537 ray_mask = 0xFF;
538 }
539 else if (visibility & PATH_RAY_SHADOW_OPAQUE) {
540 ray_flags |= OPTIX_RAY_FLAG_TERMINATE_ON_FIRST_HIT;
541 }
542
543 optixTraverse(intersection_ray_valid(ray) ? kernel_data.device_bvh : 0,
544 ray->P,
545 ray->D,
546 ray->tmin,
547 ray->tmax,
548 ray->time,
549 ray_mask,
550 ray_flags,
551 0, /* SBT offset for PG_HITD */
552 0,
553 0,
554 p0,
555 p1,
556 p2,
557 p3,
558 p4,
559 p5,
560 p6,
561 p7);
562
563 return optixHitObjectIsHit();
564}
565
566#ifdef __BVH_LOCAL__
567template<bool single_hit = false>
568ccl_device_intersect bool scene_intersect_local(KernelGlobals kg,
569 const ccl_private Ray *ray,
570 ccl_private LocalIntersection *local_isect,
571 const int local_object,
572 ccl_private uint *lcg_state,
573 const int max_hits)
574{
575 uint p0 = pointer_pack_to_uint_0(lcg_state);
576 uint p1 = pointer_pack_to_uint_1(lcg_state);
577 uint p2 = pointer_pack_to_uint_0(local_isect);
578 uint p3 = pointer_pack_to_uint_1(local_isect);
579 uint p4 = local_object;
582
583 /* Is set to zero on miss or if ray is aborted, so can be used as return value. */
584 uint p5 = max_hits;
585
586 if (local_isect) {
587 local_isect->num_hits = 0; /* Initialize hit count to zero. */
588 }
589 optixTraverse(intersection_ray_valid(ray) ? kernel_data.device_bvh : 0,
590 ray->P,
591 ray->D,
592 ray->tmin,
593 ray->tmax,
594 ray->time,
595 0xFF,
596 /* Need to always call into __anyhit__kernel_optix_local_hit. */
597 OPTIX_RAY_FLAG_ENFORCE_ANYHIT,
598 2, /* SBT offset for PG_HITL */
599 0,
600 0,
601 p0,
602 p1,
603 p2,
604 p3,
605 p4,
606 p5,
607 p6,
608 p7);
609
610 return p5;
611}
612#endif
613
614#ifdef __SHADOW_RECORD_ALL__
615ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals kg,
617 const ccl_private Ray *ray,
618 const uint visibility,
619 const uint max_transparent_hits,
620 ccl_private uint *num_recorded_hits,
621 ccl_private float *throughput)
622{
623 uint p0 = state;
624 uint p1 = __float_as_uint(1.0f); /* Throughput. */
625 uint p2 = 0; /* Number of hits. */
626 uint p3 = max_transparent_hits;
627 uint p4 = visibility;
628 uint p5 = false;
631
632 uint ray_mask = visibility & 0xFF;
633 if (0 == ray_mask && (visibility & ~0xFF) != 0) {
634 ray_mask = 0xFF;
635 }
636
637 optixTraverse(intersection_ray_valid(ray) ? kernel_data.device_bvh : 0,
638 ray->P,
639 ray->D,
640 ray->tmin,
641 ray->tmax,
642 ray->time,
643 ray_mask,
644 /* Need to always call into __anyhit__kernel_optix_shadow_all_hit. */
645 OPTIX_RAY_FLAG_ENFORCE_ANYHIT,
646 1, /* SBT offset for PG_HITS */
647 0,
648 0,
649 p0,
650 p1,
651 p2,
652 p3,
653 p4,
654 p5,
655 p6,
656 p7);
657
658 *num_recorded_hits = uint16_unpack_from_uint_0(p2);
659 *throughput = __uint_as_float(p1);
660
661 return p5;
662}
663#endif
664
665#ifdef __VOLUME__
666ccl_device_intersect bool scene_intersect_volume(KernelGlobals kg,
667 const ccl_private Ray *ray,
669 const uint visibility)
670{
671 uint p0 = 0;
672 uint p1 = 0;
673 uint p2 = 0;
674 uint p3 = 0;
675 uint p4 = visibility;
676 uint p5 = PRIMITIVE_NONE;
679
680 uint ray_mask = visibility & 0xFF;
681 if (0 == ray_mask && (visibility & ~0xFF) != 0) {
682 ray_mask = 0xFF;
683 }
684
685 optixTrace(intersection_ray_valid(ray) ? kernel_data.device_bvh : 0,
686 ray->P,
687 ray->D,
688 ray->tmin,
689 ray->tmax,
690 ray->time,
691 ray_mask,
692 /* Need to always call into __anyhit__kernel_optix_volume_test. */
693 OPTIX_RAY_FLAG_ENFORCE_ANYHIT,
694 3, /* SBT offset for PG_HITV */
695 0,
696 0,
697 p0,
698 p1,
699 p2,
700 p3,
701 p4,
702 p5,
703 p6,
704 p7);
705
706 isect->t = __uint_as_float(p0);
707 isect->u = __uint_as_float(p1);
708 isect->v = __uint_as_float(p2);
709 isect->prim = p3;
710 isect->object = p4;
711 isect->type = p5;
712
713 return p5 != PRIMITIVE_NONE;
714}
715#endif
716
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
@ SD_HAS_ONLY_VOLUME
@ 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