Blender V4.3
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_local_hit()
54{
55#if defined(__HAIR__) || defined(__POINTCLOUD__)
56 if (!optixIsTriangleHit()) {
57 /* Ignore curves and points. */
58 return optixIgnoreIntersection();
59 }
60#endif
61
62#ifdef __BVH_LOCAL__
63 const int object = get_object_id();
64 if (object != optixGetPayload_4() /* local_object */) {
65 /* Only intersect with matching object. */
66 return optixIgnoreIntersection();
67 }
68
69 const int prim = optixGetPrimitiveIndex();
71 if (intersection_skip_self_local(ray->self, prim)) {
72 return optixIgnoreIntersection();
73 }
74
75 const uint max_hits = optixGetPayload_5();
76 if (max_hits == 0) {
77 /* Special case for when no hit information is requested, just report that something was hit */
78 optixSetPayload_5(true);
79 return optixTerminateRay();
80 }
81
82 int hit = 0;
83 uint *const lcg_state = get_payload_ptr_0<uint>();
85
86 if (lcg_state) {
87 for (int i = min(max_hits, local_isect->num_hits) - 1; i >= 0; --i) {
88 if (optixGetRayTmax() == local_isect->hits[i].t) {
89 return optixIgnoreIntersection();
90 }
91 }
92
93 hit = local_isect->num_hits++;
94
95 if (local_isect->num_hits > max_hits) {
96 hit = lcg_step_uint(lcg_state) % local_isect->num_hits;
97 if (hit >= max_hits) {
98 return optixIgnoreIntersection();
99 }
100 }
101 }
102 else {
103 if (local_isect->num_hits && optixGetRayTmax() > local_isect->hits[0].t) {
104 /* Record closest intersection only.
105 * Do not terminate ray here, since there is no guarantee about distance ordering in any-hit.
106 */
107 return optixIgnoreIntersection();
108 }
109
110 local_isect->num_hits = 1;
111 }
112
113 Intersection *isect = &local_isect->hits[hit];
114 isect->t = optixGetRayTmax();
115 isect->prim = prim;
116 isect->object = get_object_id();
117 isect->type = kernel_data_fetch(objects, isect->object).primitive_type;
118
119 const float2 barycentrics = optixGetTriangleBarycentrics();
120 isect->u = barycentrics.x;
121 isect->v = barycentrics.y;
122
123 /* Record geometric normal. */
124 const packed_uint3 tri_vindex = kernel_data_fetch(tri_vindex, prim);
125 const float3 tri_a = kernel_data_fetch(tri_verts, tri_vindex.x);
126 const float3 tri_b = kernel_data_fetch(tri_verts, tri_vindex.y);
127 const float3 tri_c = kernel_data_fetch(tri_verts, tri_vindex.z);
128
129 local_isect->Ng[hit] = normalize(cross(tri_b - tri_a, tri_c - tri_a));
130
131 /* Continue tracing (without this the trace call would return after the first hit). */
132 optixIgnoreIntersection();
133#endif
134}
135
136extern "C" __global__ void __anyhit__kernel_optix_shadow_all_hit()
137{
138#ifdef __SHADOW_RECORD_ALL__
139 int prim = optixGetPrimitiveIndex();
140 const uint object = get_object_id();
141# ifdef __VISIBILITY_FLAG__
142 const uint visibility = optixGetPayload_4();
143 if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
144 return optixIgnoreIntersection();
145 }
146# endif
147
148 float u = 0.0f, v = 0.0f;
149 int type = 0;
150 if (optixIsTriangleHit()) {
151 /* Triangle. */
152 const float2 barycentrics = optixGetTriangleBarycentrics();
153 u = barycentrics.x;
154 v = barycentrics.y;
155 type = kernel_data_fetch(objects, object).primitive_type;
156 }
157# ifdef __HAIR__
158 else if ((optixGetHitKind() & (~PRIMITIVE_MOTION)) != PRIMITIVE_POINT) {
159 /* Curve. */
160 u = __uint_as_float(optixGetAttribute_0());
161 v = __uint_as_float(optixGetAttribute_1());
162
163 const KernelCurveSegment segment = kernel_data_fetch(curve_segments, prim);
164 type = segment.type;
165 prim = segment.prim;
166
167# if OPTIX_ABI_VERSION < 55
168 /* Filter out curve end-caps. */
169 if (u == 0.0f || u == 1.0f) {
170 return optixIgnoreIntersection();
171 }
172# endif
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_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 const uint num_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 if (num_hits >= max_hits ||
206 {
207 optixSetPayload_5(true);
208 return optixTerminateRay();
209 }
210
211 /* Always use baked shadow transparency for curves. */
212 if (type & PRIMITIVE_CURVE) {
213 float throughput = __uint_as_float(optixGetPayload_1());
214 throughput *= intersection_curve_shadow_transparency(nullptr, object, prim, type, u);
215 optixSetPayload_1(__float_as_uint(throughput));
216 optixSetPayload_2(uint16_pack_to_uint(num_recorded_hits, num_hits + 1));
217
218 if (throughput < CURVE_SHADOW_TRANSPARENCY_CUTOFF) {
219 optixSetPayload_5(true);
220 return optixTerminateRay();
221 }
222 else {
223 /* Continue tracing. */
224 optixIgnoreIntersection();
225 return;
226 }
227 }
228
229 /* Record transparent intersection. */
230 optixSetPayload_2(uint16_pack_to_uint(num_recorded_hits + 1, num_hits + 1));
231
232 uint record_index = num_recorded_hits;
233
234 const IntegratorShadowState state = optixGetPayload_0();
235
236 const uint max_record_hits = min(max_hits, INTEGRATOR_SHADOW_ISECT_SIZE);
237 if (record_index >= max_record_hits) {
238 /* If maximum number of hits reached, find a hit to replace. */
239 float max_recorded_t = INTEGRATOR_STATE_ARRAY(state, shadow_isect, 0, t);
240 uint max_recorded_hit = 0;
241
242 for (int i = 1; i < max_record_hits; i++) {
243 const float isect_t = INTEGRATOR_STATE_ARRAY(state, shadow_isect, i, t);
244 if (isect_t > max_recorded_t) {
245 max_recorded_t = isect_t;
246 max_recorded_hit = i;
247 }
248 }
249
250 if (optixGetRayTmax() >= max_recorded_t) {
251 /* Accept hit, so that OptiX won't consider any more hits beyond the distance of the
252 * current hit anymore. */
253 return;
254 }
255
256 record_index = max_recorded_hit;
257 }
258
259 INTEGRATOR_STATE_ARRAY_WRITE(state, shadow_isect, record_index, u) = u;
260 INTEGRATOR_STATE_ARRAY_WRITE(state, shadow_isect, record_index, v) = v;
261 INTEGRATOR_STATE_ARRAY_WRITE(state, shadow_isect, record_index, t) = optixGetRayTmax();
262 INTEGRATOR_STATE_ARRAY_WRITE(state, shadow_isect, record_index, prim) = prim;
263 INTEGRATOR_STATE_ARRAY_WRITE(state, shadow_isect, record_index, object) = object;
264 INTEGRATOR_STATE_ARRAY_WRITE(state, shadow_isect, record_index, type) = type;
265
266 /* Continue tracing. */
267 optixIgnoreIntersection();
268# endif /* __TRANSPARENT_SHADOWS__ */
269#endif /* __SHADOW_RECORD_ALL__ */
270}
271
272extern "C" __global__ void __anyhit__kernel_optix_volume_test()
273{
274#if defined(__HAIR__) || defined(__POINTCLOUD__)
275 if (!optixIsTriangleHit()) {
276 /* Ignore curves. */
277 return optixIgnoreIntersection();
278 }
279#endif
280
281 const uint object = get_object_id();
282#ifdef __VISIBILITY_FLAG__
283 const uint visibility = optixGetPayload_4();
284 if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
285 return optixIgnoreIntersection();
286 }
287#endif
288
289 if ((kernel_data_fetch(object_flag, object) & SD_OBJECT_HAS_VOLUME) == 0) {
290 return optixIgnoreIntersection();
291 }
292
293 const int prim = optixGetPrimitiveIndex();
295 if (intersection_skip_self(ray->self, object, prim)) {
296 return optixIgnoreIntersection();
297 }
298}
299
300extern "C" __global__ void __anyhit__kernel_optix_visibility_test()
301{
302#ifdef __HAIR__
303# if OPTIX_ABI_VERSION < 55
304 if (optixGetPrimitiveType() == OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BSPLINE) {
305 /* Filter out curve end-caps. */
306 const float u = __uint_as_float(optixGetAttribute_0());
307 if (u == 0.0f || u == 1.0f) {
308 return optixIgnoreIntersection();
309 }
310 }
311# endif
312#endif
313
314 const uint object = get_object_id();
315 const uint visibility = optixGetPayload_4();
316#ifdef __VISIBILITY_FLAG__
317 if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
318 return optixIgnoreIntersection();
319 }
320#endif
321
322 int prim = optixGetPrimitiveIndex();
323 if (optixIsTriangleHit()) {
324 /* Triangle. */
325 }
326#ifdef __HAIR__
327 else if ((optixGetHitKind() & (~PRIMITIVE_MOTION)) != PRIMITIVE_POINT) {
328 /* Curve. */
329 prim = kernel_data_fetch(curve_segments, prim).prim;
330 }
331#endif
332
334
335 if (visibility & PATH_RAY_SHADOW_OPAQUE) {
336#ifdef __SHADOW_LINKING__
337 if (intersection_skip_shadow_link(nullptr, ray->self, object)) {
338 return optixIgnoreIntersection();
339 }
340#endif
341
342 if (intersection_skip_self_shadow(ray->self, object, prim)) {
343 return optixIgnoreIntersection();
344 }
345 else {
346 /* Shadow ray early termination. */
347 return optixTerminateRay();
348 }
349 }
350 else {
351 if (intersection_skip_self(ray->self, object, prim)) {
352 return optixIgnoreIntersection();
353 }
354 }
355}
356
357extern "C" __global__ void __closesthit__kernel_optix_hit()
358{
359 const int object = get_object_id();
360 const int prim = optixGetPrimitiveIndex();
361
362 optixSetPayload_0(__float_as_uint(optixGetRayTmax())); /* Intersection distance */
363 optixSetPayload_4(object);
364
365 if (optixIsTriangleHit()) {
366 const float2 barycentrics = optixGetTriangleBarycentrics();
367 optixSetPayload_1(__float_as_uint(barycentrics.x));
368 optixSetPayload_2(__float_as_uint(barycentrics.y));
369 optixSetPayload_3(prim);
370 optixSetPayload_5(kernel_data_fetch(objects, object).primitive_type);
371 }
372 else if ((optixGetHitKind() & (~PRIMITIVE_MOTION)) != PRIMITIVE_POINT) {
373 const KernelCurveSegment segment = kernel_data_fetch(curve_segments, prim);
374 optixSetPayload_1(optixGetAttribute_0()); /* Same as 'optixGetCurveParameter()' */
375 optixSetPayload_2(optixGetAttribute_1());
376 optixSetPayload_3(segment.prim);
377 optixSetPayload_5(segment.type);
378 }
379 else {
380 optixSetPayload_1(0);
381 optixSetPayload_2(0);
382 optixSetPayload_3(prim);
383 optixSetPayload_5(kernel_data_fetch(objects, object).primitive_type);
384 }
385}
386
387/* Custom primitive intersection functions. */
388
389#ifdef __HAIR__
390ccl_device_inline void optix_intersection_curve(const int prim, const int type)
391{
392 const int object = get_object_id();
393
394# ifdef __VISIBILITY_FLAG__
395 const uint visibility = optixGetPayload_4();
396 if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
397 return;
398 }
399# endif
400
401 const float3 ray_P = optixGetObjectRayOrigin();
402 const float3 ray_D = optixGetObjectRayDirection();
403 const float ray_tmin = optixGetRayTmin();
404
405# ifdef __OBJECT_MOTION__
406 const float time = optixGetRayTime();
407# else
408 const float time = 0.0f;
409# endif
410
411 Intersection isect;
412 isect.t = optixGetRayTmax();
413
414 if (curve_intersect(NULL, &isect, ray_P, ray_D, ray_tmin, isect.t, object, prim, time, type)) {
415 static_assert(PRIMITIVE_ALL < 128, "Values >= 128 are reserved for OptiX internal use");
416 optixReportIntersection(isect.t,
417 type & PRIMITIVE_ALL,
418 __float_as_int(isect.u), /* Attribute_0 */
419 __float_as_int(isect.v)); /* Attribute_1 */
420 }
421}
422
423extern "C" __global__ void __intersection__curve_ribbon()
424{
425 const KernelCurveSegment segment = kernel_data_fetch(curve_segments, optixGetPrimitiveIndex());
426 const int prim = segment.prim;
427 const int type = segment.type;
428 if (type & PRIMITIVE_CURVE_RIBBON) {
429 optix_intersection_curve(prim, type);
430 }
431}
432
433#endif
434
435#ifdef __POINTCLOUD__
436extern "C" __global__ void __intersection__point()
437{
438 const int prim = optixGetPrimitiveIndex();
439 const int object = get_object_id();
440 const int type = kernel_data_fetch(objects, object).primitive_type;
441
442# ifdef __VISIBILITY_FLAG__
443 const uint visibility = optixGetPayload_4();
444 if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
445 return;
446 }
447# endif
448
449 const float3 ray_P = optixGetObjectRayOrigin();
450 const float3 ray_D = optixGetObjectRayDirection();
451 const float ray_tmin = optixGetRayTmin();
452
453# ifdef __OBJECT_MOTION__
454 const float time = optixGetRayTime();
455# else
456 const float time = 0.0f;
457# endif
458
459 Intersection isect;
460 isect.t = optixGetRayTmax();
461
462 if (point_intersect(NULL, &isect, ray_P, ray_D, ray_tmin, isect.t, object, prim, time, type)) {
463 static_assert(PRIMITIVE_ALL < 128, "Values >= 128 are reserved for OptiX internal use");
464 optixReportIntersection(isect.t, type & PRIMITIVE_ALL);
465 }
466}
467#endif
468
469/* Scene intersection. */
470
472 ccl_private const Ray *ray,
473 const uint visibility,
475{
476 uint p0 = 0;
477 uint p1 = 0;
478 uint p2 = 0;
479 uint p3 = 0;
480 uint p4 = visibility;
481 uint p5 = PRIMITIVE_NONE;
482 uint p6 = ((uint64_t)ray) & 0xFFFFFFFF;
483 uint p7 = (((uint64_t)ray) >> 32) & 0xFFFFFFFF;
484
485 uint ray_mask = visibility & 0xFF;
486 uint ray_flags = OPTIX_RAY_FLAG_ENFORCE_ANYHIT;
487 if (0 == ray_mask && (visibility & ~0xFF) != 0) {
488 ray_mask = 0xFF;
489 }
490 else if (visibility & PATH_RAY_SHADOW_OPAQUE) {
491 ray_flags |= OPTIX_RAY_FLAG_TERMINATE_ON_FIRST_HIT;
492 }
493
494 optixTrace(intersection_ray_valid(ray) ? kernel_data.device_bvh : 0,
495 ray->P,
496 ray->D,
497 ray->tmin,
498 ray->tmax,
499 ray->time,
500 ray_mask,
501 ray_flags,
502 0, /* SBT offset for PG_HITD */
503 0,
504 0,
505 p0,
506 p1,
507 p2,
508 p3,
509 p4,
510 p5,
511 p6,
512 p7);
513
514 isect->t = __uint_as_float(p0);
515 isect->u = __uint_as_float(p1);
516 isect->v = __uint_as_float(p2);
517 isect->prim = p3;
518 isect->object = p4;
519 isect->type = p5;
520
521 return p5 != PRIMITIVE_NONE;
522}
523
525 ccl_private const Ray *ray,
526 const uint visibility)
527{
528 Intersection isect;
529 return scene_intersect(kg, ray, visibility, &isect);
530}
531
532#ifdef __BVH_LOCAL__
533template<bool single_hit = false>
534ccl_device_intersect bool scene_intersect_local(KernelGlobals kg,
535 ccl_private const Ray *ray,
536 ccl_private LocalIntersection *local_isect,
537 int local_object,
538 ccl_private uint *lcg_state,
539 int max_hits)
540{
541 uint p0 = pointer_pack_to_uint_0(lcg_state);
542 uint p1 = pointer_pack_to_uint_1(lcg_state);
543 uint p2 = pointer_pack_to_uint_0(local_isect);
544 uint p3 = pointer_pack_to_uint_1(local_isect);
545 uint p4 = local_object;
546 uint p6 = ((uint64_t)ray) & 0xFFFFFFFF;
547 uint p7 = (((uint64_t)ray) >> 32) & 0xFFFFFFFF;
548
549 /* Is set to zero on miss or if ray is aborted, so can be used as return value. */
550 uint p5 = max_hits;
551
552 if (local_isect) {
553 local_isect->num_hits = 0; /* Initialize hit count to zero. */
554 }
555 optixTrace(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 0xFF,
562 /* Need to always call into __anyhit__kernel_optix_local_hit. */
563 OPTIX_RAY_FLAG_ENFORCE_ANYHIT,
564 2, /* SBT offset for PG_HITL */
565 0,
566 0,
567 p0,
568 p1,
569 p2,
570 p3,
571 p4,
572 p5,
573 p6,
574 p7);
575
576 return p5;
577}
578#endif
579
580#ifdef __SHADOW_RECORD_ALL__
581ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals kg,
583 ccl_private const Ray *ray,
584 uint visibility,
585 uint max_hits,
586 ccl_private uint *num_recorded_hits,
587 ccl_private float *throughput)
588{
589 uint p0 = state;
590 uint p1 = __float_as_uint(1.0f); /* Throughput. */
591 uint p2 = 0; /* Number of hits. */
592 uint p3 = max_hits;
593 uint p4 = visibility;
594 uint p5 = false;
595 uint p6 = ((uint64_t)ray) & 0xFFFFFFFF;
596 uint p7 = (((uint64_t)ray) >> 32) & 0xFFFFFFFF;
597
598 uint ray_mask = visibility & 0xFF;
599 if (0 == ray_mask && (visibility & ~0xFF) != 0) {
600 ray_mask = 0xFF;
601 }
602
603 optixTrace(intersection_ray_valid(ray) ? kernel_data.device_bvh : 0,
604 ray->P,
605 ray->D,
606 ray->tmin,
607 ray->tmax,
608 ray->time,
609 ray_mask,
610 /* Need to always call into __anyhit__kernel_optix_shadow_all_hit. */
611 OPTIX_RAY_FLAG_ENFORCE_ANYHIT,
612 1, /* SBT offset for PG_HITS */
613 0,
614 0,
615 p0,
616 p1,
617 p2,
618 p3,
619 p4,
620 p5,
621 p6,
622 p7);
623
624 *num_recorded_hits = uint16_unpack_from_uint_0(p2);
625 *throughput = __uint_as_float(p1);
626
627 return p5;
628}
629#endif
630
631#ifdef __VOLUME__
632ccl_device_intersect bool scene_intersect_volume(KernelGlobals kg,
633 ccl_private const Ray *ray,
635 const uint visibility)
636{
637 uint p0 = 0;
638 uint p1 = 0;
639 uint p2 = 0;
640 uint p3 = 0;
641 uint p4 = visibility;
642 uint p5 = PRIMITIVE_NONE;
643 uint p6 = ((uint64_t)ray) & 0xFFFFFFFF;
644 uint p7 = (((uint64_t)ray) >> 32) & 0xFFFFFFFF;
645
646 uint ray_mask = visibility & 0xFF;
647 if (0 == ray_mask && (visibility & ~0xFF) != 0) {
648 ray_mask = 0xFF;
649 }
650
651 optixTrace(intersection_ray_valid(ray) ? kernel_data.device_bvh : 0,
652 ray->P,
653 ray->D,
654 ray->tmin,
655 ray->tmax,
656 ray->time,
657 ray_mask,
658 /* Need to always call into __anyhit__kernel_optix_volume_test. */
659 OPTIX_RAY_FLAG_ENFORCE_ANYHIT,
660 3, /* SBT offset for PG_HITV */
661 0,
662 0,
663 p0,
664 p1,
665 p2,
666 p3,
667 p4,
668 p5,
669 p6,
670 p7);
671
672 isect->t = __uint_as_float(p0);
673 isect->u = __uint_as_float(p1);
674 isect->v = __uint_as_float(p2);
675 isect->prim = p3;
676 isect->object = p4;
677 isect->type = p5;
678
679 return p5 != PRIMITIVE_NONE;
680}
681#endif
682
unsigned int uint
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition btVector3.h:303
ccl_device_forceinline int intersection_get_shader_flags(KernelGlobals kg, const int prim, const int type)
ccl_device_inline bool intersection_skip_self_local(ccl_ray_data const RaySelfPrimitives &self, const int prim)
ccl_device_inline bool intersection_skip_self(ccl_ray_data const RaySelfPrimitives &self, const int object, const int prim)
ccl_device_inline bool intersection_skip_shadow_link(KernelGlobals kg, ccl_ray_data const RaySelfPrimitives &self, const int isect_object)
#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_shadow(ccl_ray_data const RaySelfPrimitives &self, const int object, const int prim)
CCL_NAMESPACE_BEGIN ccl_device_inline bool intersection_ray_valid(ccl_private const Ray *ray)
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
#define ccl_device_forceinline
#define ccl_private
#define ccl_device_inline
#define CCL_NAMESPACE_END
#define NULL
#define __float_as_int(x)
#define __float_as_uint(x)
#define __uint_as_float(x)
#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()
ccl_device_intersect bool scene_intersect(KernelGlobals kg, ccl_private const Ray *ray, const uint visibility, ccl_private Intersection *isect)
__global__ void __anyhit__kernel_optix_local_hit()
__global__ void __anyhit__kernel_optix_shadow_all_hit()
__global__ void __closesthit__kernel_optix_hit()
ccl_device_intersect bool scene_intersect_shadow(KernelGlobals kg, ccl_private const Ray *ray, const uint visibility)
ccl_device_forceinline T * get_payload_ptr_2()
CCL_NAMESPACE_BEGIN ccl_device_forceinline T * get_payload_ptr_0()
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
#define INTEGRATOR_SHADOW_ISECT_SIZE
@ SD_OBJECT_HAS_VOLUME
CCL_NAMESPACE_BEGIN ccl_device uint lcg_step_uint(T rng)
Definition lcg.h:14
ccl_device_inline float cross(const float2 a, const float2 b)
static ulong state[N]
#define min(a, b)
Definition sort.c:32
#define INTEGRATOR_STATE_ARRAY_WRITE(state, nested_struct, array_index, member)
Definition state.h:240
IntegratorShadowStateCPU *ccl_restrict IntegratorShadowState
Definition state.h:230
#define INTEGRATOR_STATE_ARRAY(state, nested_struct, array_index, member)
Definition state.h:238
unsigned __int64 uint64_t
Definition stdint.h:90
struct Intersection hits[LOCAL_MAX_HITS]
float3 Ng[LOCAL_MAX_HITS]
float x
float y
ccl_device_inline uint uint16_unpack_from_uint_1(const uint i)
Definition util/math.h:353
ccl_device_inline uint pointer_pack_to_uint_1(T *ptr)
Definition util/math.h:333
ccl_device_inline uint uint16_pack_to_uint(const uint a, const uint b)
Definition util/math.h:343
ccl_device_inline uint pointer_pack_to_uint_0(T *ptr)
Definition util/math.h:328
ccl_device_inline T * pointer_unpack_from_uint(const uint a, const uint b)
Definition util/math.h:338
ccl_device_inline uint uint16_unpack_from_uint_0(const uint i)
Definition util/math.h:348