28#if defined(__METALRT_MOTION__)
35#if defined(__METALRT_MOTION__)
48 "MetalRTIntersectionLocalPayload max_hits & num_hits bitfields are too small");
89 const float r = metal::catmull_rom(u, radius[0], radius[1], radius[2], radius[3]);
96# if defined(__METALRT_MOTION__)
97 bvh_instance_motion_push(
nullptr,
object, ray, &ray_P, &ray_D, &idir);
104 const float avoidance_factor = 2.0f;
105 return t *
len(ray_D) > avoidance_factor * r;
116# if defined(__METALRT_MOTION__)
117 float time = ray->time;
139 motion_curve_keys(kg,
object, time, ka, k0, k1, kb, curve);
146# if defined(__METALRT_MOTION__)
147 bvh_instance_motion_push(
nullptr,
object, ray, &ray_P, &ray_D, &idir);
153 const float4 P_curve4 = metal::catmull_rom(u, curve[0], curve[1], curve[2], curve[3]);
154 const float r_curve = P_curve4.
w;
159 const float4 dPdu4 = metal::catmull_rom_derivative(u, curve[0], curve[1], curve[2], curve[3]);
165 float v =
dot(
P - P_curve, bitangent) / r_curve;
166 return clamp(
v, -1.0, 1.0f);
174 const uint visibility,
177 metal::raytracing::ray r(ray->P, ray->D, ray->tmin, ray->tmax);
178 metalrt_intersector_type metalrt_intersect;
179 metalrt_intersect.force_opacity(metal::raytracing::forced_opacity::non_opaque);
180 metalrt_intersect.assume_geometry_type(
181 metal::raytracing::geometry_type::triangle |
182 (
kernel_data.bvh.have_curves ? metal::raytracing::geometry_type::curve :
183 metal::raytracing::geometry_type::none) |
184 (
kernel_data.bvh.have_points ? metal::raytracing::geometry_type::bounding_box :
185 metal::raytracing::geometry_type::none));
187 typename metalrt_intersector_type::result_type intersection;
194 uint ray_mask = visibility & 0xFF;
195 if (0 == ray_mask && (visibility & ~0xFF) != 0) {
199#if defined(__METALRT_MOTION__)
200 intersection = metalrt_intersect.intersect(r,
201 metal_ancillaries->accel_struct,
204 metal_ancillaries->ift_default,
207 intersection = metalrt_intersect.intersect(
208 r, metal_ancillaries->accel_struct, ray_mask, metal_ancillaries->ift_default, payload);
211 if (intersection.type == intersection_type::none) {
212 isect->t = ray->tmax;
218 isect->object = intersection.instance_id;
219 isect->t = intersection.distance;
220 if (intersection.type == intersection_type::triangle) {
221 isect->prim = intersection.primitive_id + intersection.user_instance_id;
222 isect->type =
kernel_data_fetch(objects, intersection.instance_id).primitive_type;
223 isect->u = intersection.triangle_barycentric_coord.x;
224 isect->v = intersection.triangle_barycentric_coord.y;
227 else if (
kernel_data.bvh.have_curves && intersection.type == intersection_type::curve) {
228 int prim = intersection.primitive_id + intersection.user_instance_id;
230 isect->prim = segment.prim;
231 isect->type = segment.type;
232 isect->u = intersection.curve_parameter;
235 isect->v = curve_ribbon_v(kg,
236 intersection.curve_parameter,
237 intersection.distance,
239 intersection.instance_id,
249 else if (
kernel_data.bvh.have_points && intersection.type == intersection_type::bounding_box) {
250 const int object = intersection.instance_id;
251 const uint prim = intersection.primitive_id + intersection.user_instance_id;
256# if defined(__METALRT_MOTION__)
257 bvh_instance_motion_push(
nullptr,
object, ray, &r.origin, &r.direction, &idir);
264 if (!point_intersect(
nullptr,
277 isect->t = ray->tmax;
291 const uint visibility)
293 metal::raytracing::ray r(ray->P, ray->D, ray->tmin, ray->tmax);
294 metalrt_intersector_type metalrt_intersect;
295 metalrt_intersect.force_opacity(metal::raytracing::forced_opacity::non_opaque);
296 metalrt_intersect.assume_geometry_type(
297 metal::raytracing::geometry_type::triangle |
298 (
kernel_data.bvh.have_curves ? metal::raytracing::geometry_type::curve :
299 metal::raytracing::geometry_type::none) |
300 (
kernel_data.bvh.have_points ? metal::raytracing::geometry_type::bounding_box :
301 metal::raytracing::geometry_type::none));
303 typename metalrt_intersector_type::result_type intersection;
305 metalrt_intersect.accept_any_intersection(
true);
308 payload.
self = ray->self;
311 uint ray_mask = visibility & 0xFF;
312 if (0 == ray_mask && (visibility & ~0xFF) != 0) {
316#if defined(__METALRT_MOTION__)
317 intersection = metalrt_intersect.intersect(r,
318 metal_ancillaries->accel_struct,
321 metal_ancillaries->ift_shadow,
324 intersection = metalrt_intersect.intersect(
325 r, metal_ancillaries->accel_struct, ray_mask, metal_ancillaries->ift_shadow, payload);
327 return (intersection.type != intersection_type::none);
331template<
bool single_hit = false>
335 const int local_object,
341 metal::raytracing::ray r(ray->P, ray->D, ray->tmin, ray->tmax);
343# if defined(__METALRT_MOTION__)
344 metalrt_intersector_type metalrt_intersect;
345 typename metalrt_intersector_type::result_type
intersection;
347 metalrt_blas_intersector_type metalrt_intersect;
348 typename metalrt_blas_intersector_type::result_type
intersection;
358 metalrt_intersect.assume_geometry_type(metal::raytracing::geometry_type::triangle);
362 payload.
self_prim = ray->self.prim - primitive_id_offset;
364# if defined(__METALRT_MOTION__)
367 payload.self_object = local_object;
368 metalrt_intersect.force_opacity(metal::raytracing::forced_opacity::non_opaque);
370 metal_ancillaries->accel_struct,
373 metal_ancillaries->ift_local_single_hit_mblur,
378 metalrt_intersect.force_opacity((ray->self.prim ==
PRIM_NONE) ?
379 metal::raytracing::forced_opacity::opaque :
380 metal::raytracing::forced_opacity::non_opaque);
383 metal_ancillaries->blas_accel_structs[local_object].blas,
384 metal_ancillaries->ift_local_single_hit,
389 local_isect->num_hits = 0;
396 local_isect->num_hits = 1;
397 local_isect->hits[0].prim = prim;
398 local_isect->hits[0].type = prim_type;
399 local_isect->hits[0].object = local_object;
400 local_isect->hits[0].u =
intersection.triangle_barycentric_coord.x;
401 local_isect->hits[0].v =
intersection.triangle_barycentric_coord.y;
408 local_isect->Ng[0] =
normalize(
cross(tri_b - tri_a, tri_c - tri_a));
413 payload.
self_prim = ray->self.prim - primitive_id_offset;
421 metalrt_intersect.force_opacity(metal::raytracing::forced_opacity::non_opaque);
423# if defined(__METALRT_MOTION__)
426 payload.self_object = local_object;
428 metal_ancillaries->accel_struct,
431 metal_ancillaries->ift_local_mblur,
436 metal_ancillaries->blas_accel_structs[local_object].blas,
437 metal_ancillaries->ift_local,
451 const int num_hits = payload.
num_hits;
457 local_isect->num_hits = num_hits;
458 for (
int hit = 0; hit < num_hits; hit++) {
459 uint prim = payload.
hit_prim[hit] + primitive_id_offset;
460 local_isect->hits[hit].prim = prim;
461 local_isect->hits[hit].t = payload.
hit_t[hit];
462 local_isect->hits[hit].u = payload.
hit_u[hit];
463 local_isect->hits[hit].v = payload.
hit_v[hit];
464 local_isect->hits[hit].object = local_object;
465 local_isect->hits[hit].type = prim_type;
471 local_isect->Ng[hit] =
normalize(
cross(tri_b - tri_a, tri_c - tri_a));
479#ifdef __SHADOW_RECORD_ALL__
483 const uint visibility,
484 const uint max_transparent_hits,
488 metal::raytracing::ray r(ray->P, ray->D, ray->tmin, ray->tmax);
489 metalrt_intersector_type metalrt_intersect;
490 metalrt_intersect.force_opacity(metal::raytracing::forced_opacity::non_opaque);
491 metalrt_intersect.assume_geometry_type(
492 metal::raytracing::geometry_type::triangle |
493 (
kernel_data.bvh.have_curves ? metal::raytracing::geometry_type::curve :
494 metal::raytracing::geometry_type::none) |
495 (
kernel_data.bvh.have_points ? metal::raytracing::geometry_type::bounding_box :
496 metal::raytracing::geometry_type::none));
499 payload.
self = ray->self;
508 uint ray_mask = visibility & 0xFF;
509 if (0 == ray_mask && (visibility & ~0xFF) != 0) {
513 typename metalrt_intersector_type::result_type
intersection;
515# if defined(__METALRT_MOTION__)
517 metal_ancillaries->accel_struct,
520 metal_ancillaries->ift_shadow_all,
524 r, metal_ancillaries->accel_struct, ray_mask, metal_ancillaries->ift_shadow_all, payload);
538 const uint visibility)
540 metal::raytracing::ray r(ray->P, ray->D, ray->tmin, ray->tmax);
541 metalrt_intersector_type metalrt_intersect;
542 metalrt_intersect.force_opacity(metal::raytracing::forced_opacity::non_opaque);
543 metalrt_intersect.set_geometry_cull_mode(metal::raytracing::geometry_cull_mode::bounding_box |
544 metal::raytracing::geometry_cull_mode::curve);
545 metalrt_intersect.assume_geometry_type(
546 metal::raytracing::geometry_type::triangle |
547 (
kernel_data.bvh.have_curves ? metal::raytracing::geometry_type::curve :
548 metal::raytracing::geometry_type::none) |
549 (
kernel_data.bvh.have_points ? metal::raytracing::geometry_type::bounding_box :
550 metal::raytracing::geometry_type::none));
553 payload.
self = ray->self;
556 uint ray_mask = visibility & 0xFF;
557 if (0 == ray_mask && (visibility & ~0xFF) != 0) {
561 typename metalrt_intersector_type::result_type
intersection;
563# if defined(__METALRT_MOTION__)
565 metal_ancillaries->accel_struct,
568 metal_ancillaries->ift_volume,
572 r, metal_ancillaries->accel_struct, ray_mask, 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, D > normalize(VecOp< float, D >) RET
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
constexpr T clamp(T, U, U) RET
VecBase< float, 3 > float3
#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