27#if defined(__METALRT_MOTION__)
34#if defined(__METALRT_MOTION__)
47 "MetalRTIntersectionLocalPayload max_hits & num_hits bitfields are too small");
86 const float r = metal::catmull_rom(u, radius[0], radius[1], radius[2], radius[3]);
93# if defined(__METALRT_MOTION__)
94 bvh_instance_motion_push(
nullptr,
object, ray, &ray_P, &ray_D, &idir);
101 const float avoidance_factor = 2.0f;
102 return t *
len(ray_D) > avoidance_factor * r;
113# if defined(__METALRT_MOTION__)
114 float time = ray->time;
136 motion_curve_keys(kg,
object, time, ka, k0, k1, kb, curve);
143# if defined(__METALRT_MOTION__)
144 bvh_instance_motion_push(
nullptr,
object, ray, &ray_P, &ray_D, &idir);
150 const float4 P_curve4 = metal::catmull_rom(u, curve[0], curve[1], curve[2], curve[3]);
151 const float r_curve = P_curve4.w;
156 const float4 dPdu4 = metal::catmull_rom_derivative(u, curve[0], curve[1], curve[2], curve[3]);
162 float v =
dot(
P - P_curve, bitangent) / r_curve;
163 return clamp(
v, -1.0, 1.0f);
171 const uint visibility,
174 metal::raytracing::ray r(ray->P, ray->D, ray->tmin, ray->tmax);
175 metalrt_intersector_type metalrt_intersect;
176 metalrt_intersect.force_opacity(metal::raytracing::forced_opacity::non_opaque);
177 metalrt_intersect.assume_geometry_type(
178 metal::raytracing::geometry_type::triangle |
179 (
kernel_data.bvh.have_curves ? metal::raytracing::geometry_type::curve :
180 metal::raytracing::geometry_type::none) |
181 (
kernel_data.bvh.have_points ? metal::raytracing::geometry_type::bounding_box :
182 metal::raytracing::geometry_type::none));
184 typename metalrt_intersector_type::result_type intersection;
190#if defined(__METALRT_MOTION__)
191 intersection = metalrt_intersect.intersect(r,
192 metal_ancillaries->accel_struct,
195 metal_ancillaries->ift_default,
198 intersection = metalrt_intersect.intersect(
199 r, metal_ancillaries->accel_struct, visibility, metal_ancillaries->ift_default, payload);
202 if (intersection.type == intersection_type::none) {
203 isect->t = ray->tmax;
209 isect->object = intersection.instance_id;
210 isect->t = intersection.distance;
211 if (intersection.type == intersection_type::triangle) {
212 isect->prim = intersection.primitive_id + intersection.user_instance_id;
213 isect->type =
kernel_data_fetch(objects, intersection.instance_id).primitive_type;
214 isect->u = intersection.triangle_barycentric_coord.x;
215 isect->v = intersection.triangle_barycentric_coord.y;
218 else if (
kernel_data.bvh.have_curves && intersection.type == intersection_type::curve) {
219 int prim = intersection.primitive_id + intersection.user_instance_id;
221 isect->prim = segment.prim;
222 isect->type = segment.type;
223 isect->u = intersection.curve_parameter;
226 isect->v = curve_ribbon_v(kg,
227 intersection.curve_parameter,
228 intersection.distance,
230 intersection.instance_id,
240 else if (
kernel_data.bvh.have_points && intersection.type == intersection_type::bounding_box) {
241 const int object = intersection.instance_id;
242 const uint prim = intersection.primitive_id + intersection.user_instance_id;
247# if defined(__METALRT_MOTION__)
248 bvh_instance_motion_push(
nullptr,
object, ray, &r.origin, &r.direction, &idir);
255 if (!point_intersect(
nullptr,
268 isect->t = ray->tmax;
282 const uint visibility)
284 metal::raytracing::ray r(ray->P, ray->D, ray->tmin, ray->tmax);
285 metalrt_intersector_type metalrt_intersect;
286 metalrt_intersect.force_opacity(metal::raytracing::forced_opacity::non_opaque);
287 metalrt_intersect.assume_geometry_type(
288 metal::raytracing::geometry_type::triangle |
289 (
kernel_data.bvh.have_curves ? metal::raytracing::geometry_type::curve :
290 metal::raytracing::geometry_type::none) |
291 (
kernel_data.bvh.have_points ? metal::raytracing::geometry_type::bounding_box :
292 metal::raytracing::geometry_type::none));
294 typename metalrt_intersector_type::result_type intersection;
296 metalrt_intersect.accept_any_intersection(
true);
299 payload.
self = ray->self;
301#if defined(__METALRT_MOTION__)
302 intersection = metalrt_intersect.intersect(r,
303 metal_ancillaries->accel_struct,
306 metal_ancillaries->ift_shadow,
309 intersection = metalrt_intersect.intersect(
310 r, metal_ancillaries->accel_struct, visibility, metal_ancillaries->ift_shadow, payload);
312 return (intersection.type != intersection_type::none);
316template<
bool single_hit = false>
320 const int local_object,
326 metal::raytracing::ray r(ray->P, ray->D, ray->tmin, ray->tmax);
328# if defined(__METALRT_MOTION__)
329 metalrt_intersector_type metalrt_intersect;
330 typename metalrt_intersector_type::result_type
intersection;
332 metalrt_blas_intersector_type metalrt_intersect;
333 typename metalrt_blas_intersector_type::result_type
intersection;
343 metalrt_intersect.assume_geometry_type(metal::raytracing::geometry_type::triangle);
347 payload.
self_prim = ray->self.prim - primitive_id_offset;
349# if defined(__METALRT_MOTION__)
352 payload.self_object = local_object;
353 metalrt_intersect.force_opacity(metal::raytracing::forced_opacity::non_opaque);
355 metal_ancillaries->accel_struct,
358 metal_ancillaries->ift_local_single_hit_mblur,
363 metalrt_intersect.force_opacity((ray->self.prim ==
PRIM_NONE) ?
364 metal::raytracing::forced_opacity::opaque :
365 metal::raytracing::forced_opacity::non_opaque);
368 metal_ancillaries->blas_accel_structs[local_object].blas,
369 metal_ancillaries->ift_local_single_hit,
374 local_isect->num_hits = 0;
381 local_isect->num_hits = 1;
382 local_isect->hits[0].prim = prim;
383 local_isect->hits[0].type = prim_type;
384 local_isect->hits[0].object = local_object;
385 local_isect->hits[0].u =
intersection.triangle_barycentric_coord.x;
386 local_isect->hits[0].v =
intersection.triangle_barycentric_coord.y;
393 local_isect->Ng[0] =
normalize(
cross(tri_b - tri_a, tri_c - tri_a));
398 payload.
self_prim = ray->self.prim - primitive_id_offset;
406 metalrt_intersect.force_opacity(metal::raytracing::forced_opacity::non_opaque);
408# if defined(__METALRT_MOTION__)
411 payload.self_object = local_object;
413 metal_ancillaries->accel_struct,
416 metal_ancillaries->ift_local_mblur,
421 metal_ancillaries->blas_accel_structs[local_object].blas,
422 metal_ancillaries->ift_local,
436 const int num_hits = payload.
num_hits;
442 local_isect->num_hits = num_hits;
443 for (
int hit = 0; hit < num_hits; hit++) {
444 uint prim = payload.
hit_prim[hit] + primitive_id_offset;
445 local_isect->hits[hit].prim = prim;
446 local_isect->hits[hit].t = payload.
hit_t[hit];
447 local_isect->hits[hit].u = payload.
hit_u[hit];
448 local_isect->hits[hit].v = payload.
hit_v[hit];
449 local_isect->hits[hit].object = local_object;
450 local_isect->hits[hit].type = prim_type;
456 local_isect->Ng[hit] =
normalize(
cross(tri_b - tri_a, tri_c - tri_a));
464#ifdef __SHADOW_RECORD_ALL__
468 const uint visibility,
473 metal::raytracing::ray r(ray->P, ray->D, ray->tmin, ray->tmax);
474 metalrt_intersector_type metalrt_intersect;
475 metalrt_intersect.force_opacity(metal::raytracing::forced_opacity::non_opaque);
476 metalrt_intersect.assume_geometry_type(
477 metal::raytracing::geometry_type::triangle |
478 (
kernel_data.bvh.have_curves ? metal::raytracing::geometry_type::curve :
479 metal::raytracing::geometry_type::none) |
480 (
kernel_data.bvh.have_points ? metal::raytracing::geometry_type::bounding_box :
481 metal::raytracing::geometry_type::none));
484 payload.
self = ray->self;
492 typename metalrt_intersector_type::result_type
intersection;
494# if defined(__METALRT_MOTION__)
496 metal_ancillaries->accel_struct,
499 metal_ancillaries->ift_shadow_all,
503 r, metal_ancillaries->accel_struct, visibility, metal_ancillaries->ift_shadow_all, payload);
517 const uint visibility)
519 metal::raytracing::ray r(ray->P, ray->D, ray->tmin, ray->tmax);
520 metalrt_intersector_type metalrt_intersect;
521 metalrt_intersect.force_opacity(metal::raytracing::forced_opacity::non_opaque);
522 metalrt_intersect.set_geometry_cull_mode(metal::raytracing::geometry_cull_mode::bounding_box |
523 metal::raytracing::geometry_cull_mode::curve);
524 metalrt_intersect.assume_geometry_type(
525 metal::raytracing::geometry_type::triangle |
526 (
kernel_data.bvh.have_curves ? metal::raytracing::geometry_type::curve :
527 metal::raytracing::geometry_type::none) |
528 (
kernel_data.bvh.have_points ? metal::raytracing::geometry_type::bounding_box :
529 metal::raytracing::geometry_type::none));
532 payload.
self = ray->self;
534 typename metalrt_intersector_type::result_type
intersection;
536# if defined(__METALRT_MOTION__)
538 metal_ancillaries->accel_struct,
541 metal_ancillaries->ift_volume,
545 r, metal_ancillaries->accel_struct, visibility, metal_ancillaries->ift_volume, payload);
ATTR_WARN_UNUSED_RESULT const BMVert * v
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
#define kernel_assert(cond)
#define ccl_device_forceinline
#define kernel_data_fetch(name, index)
#define PRIMITIVE_UNPACK_SEGMENT(type)
const ThreadKernelGlobalsCPU * KernelGlobals
#define CCL_NAMESPACE_END
VecBase< float, 4 > float4
VecBase< float, D > normalize(VecOp< float, D >) RET
VecBase< float, 3 > float3
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
constexpr T clamp(T, U, U) RET
#define ccl_device_intersect
ccl_device_inline void bvh_instance_push(KernelGlobals kg, const int object, const ccl_private Ray *ray, ccl_private float3 *P, ccl_private float3 *dir, ccl_private float3 *idir)
@ SD_OBJECT_TRANSFORM_APPLIED
Intersection< segment > intersection
IntegratorShadowStateCPU * IntegratorShadowState