27#if defined(__METALRT_MOTION__)
34#if defined(__METALRT_MOTION__)
47 "MetalRTIntersectionLocalPayload max_hits & num_hits bitfields are too small");
81 const float r = metal::catmull_rom(u, radius[0], radius[1], radius[2], radius[3]);
88# if defined(__METALRT_MOTION__)
89 bvh_instance_motion_push(
NULL,
object, ray, &ray_P, &ray_D, &idir);
96 const float avoidance_factor = 2.0f;
97 return t *
len(ray_D) > avoidance_factor * r;
103# if defined(__METALRT_MOTION__)
104 float time = ray->time;
126 motion_curve_keys(kg,
object, time, ka, k0, k1, kb, curve);
133# if defined(__METALRT_MOTION__)
134 bvh_instance_motion_push(
NULL,
object, ray, &ray_P, &ray_D, &idir);
140 const float4 P_curve4 = metal::catmull_rom(u, curve[0], curve[1], curve[2], curve[3]);
141 const float r_curve = P_curve4.w;
146 const float4 dPdu4 = metal::catmull_rom_derivative(u, curve[0], curve[1], curve[2], curve[3]);
152 float v =
dot(
P - P_curve, bitangent) / r_curve;
153 return clamp(
v, -1.0, 1.0f);
161 const uint visibility,
164 metal::raytracing::ray r(ray->P, ray->D, ray->tmin, ray->tmax);
165 metalrt_intersector_type metalrt_intersect;
166 metalrt_intersect.force_opacity(metal::raytracing::forced_opacity::non_opaque);
167 metalrt_intersect.assume_geometry_type(
168 metal::raytracing::geometry_type::triangle |
169 (
kernel_data.bvh.have_curves ? metal::raytracing::geometry_type::curve :
170 metal::raytracing::geometry_type::none) |
171 (
kernel_data.bvh.have_points ? metal::raytracing::geometry_type::bounding_box :
172 metal::raytracing::geometry_type::none));
174 typename metalrt_intersector_type::result_type intersection;
180#if defined(__METALRT_MOTION__)
181 intersection = metalrt_intersect.intersect(r,
182 metal_ancillaries->accel_struct,
185 metal_ancillaries->ift_default,
188 intersection = metalrt_intersect.intersect(
189 r, metal_ancillaries->accel_struct, visibility, metal_ancillaries->ift_default, payload);
192 if (intersection.type == intersection_type::none) {
193 isect->t = ray->tmax;
199 isect->object = intersection.instance_id;
200 isect->t = intersection.distance;
201 if (intersection.type == intersection_type::triangle) {
202 isect->prim = intersection.primitive_id + intersection.user_instance_id;
203 isect->type =
kernel_data_fetch(objects, intersection.instance_id).primitive_type;
204 isect->u = intersection.triangle_barycentric_coord.x;
205 isect->v = intersection.triangle_barycentric_coord.y;
208 else if (
kernel_data.bvh.have_curves && intersection.type == intersection_type::curve) {
209 int prim = intersection.primitive_id + intersection.user_instance_id;
211 isect->prim = segment.prim;
212 isect->type = segment.type;
213 isect->u = intersection.curve_parameter;
216 isect->v = curve_ribbon_v(kg,
217 intersection.curve_parameter,
218 intersection.distance,
220 intersection.instance_id,
230 else if (
kernel_data.bvh.have_points && intersection.type == intersection_type::bounding_box) {
231 const int object = intersection.instance_id;
232 const uint prim = intersection.primitive_id + intersection.user_instance_id;
237# if defined(__METALRT_MOTION__)
238 bvh_instance_motion_push(
NULL,
object, ray, &r.origin, &r.direction, &idir);
245 if (!point_intersect(
NULL,
258 isect->t = ray->tmax;
272 const uint visibility)
274 metal::raytracing::ray r(ray->P, ray->D, ray->tmin, ray->tmax);
275 metalrt_intersector_type metalrt_intersect;
276 metalrt_intersect.force_opacity(metal::raytracing::forced_opacity::non_opaque);
277 metalrt_intersect.assume_geometry_type(
278 metal::raytracing::geometry_type::triangle |
279 (
kernel_data.bvh.have_curves ? metal::raytracing::geometry_type::curve :
280 metal::raytracing::geometry_type::none) |
281 (
kernel_data.bvh.have_points ? metal::raytracing::geometry_type::bounding_box :
282 metal::raytracing::geometry_type::none));
284 typename metalrt_intersector_type::result_type intersection;
286 metalrt_intersect.accept_any_intersection(
true);
289 payload.
self = ray->self;
291#if defined(__METALRT_MOTION__)
292 intersection = metalrt_intersect.intersect(r,
293 metal_ancillaries->accel_struct,
296 metal_ancillaries->ift_shadow,
299 intersection = metalrt_intersect.intersect(
300 r, metal_ancillaries->accel_struct, visibility, metal_ancillaries->ift_shadow, payload);
302 return (intersection.type != intersection_type::none);
306template<
bool single_hit = false>
316 metal::raytracing::ray r(ray->P, ray->D, ray->tmin, ray->tmax);
318# if defined(__METALRT_MOTION__)
319 metalrt_intersector_type metalrt_intersect;
320 typename metalrt_intersector_type::result_type
intersection;
322 metalrt_blas_intersector_type metalrt_intersect;
323 typename metalrt_blas_intersector_type::result_type
intersection;
333 metalrt_intersect.assume_geometry_type(metal::raytracing::geometry_type::triangle);
337 payload.
self_prim = ray->self.prim - primitive_id_offset;
339# if defined(__METALRT_MOTION__)
342 payload.self_object = local_object;
343 metalrt_intersect.force_opacity(metal::raytracing::forced_opacity::non_opaque);
345 metal_ancillaries->accel_struct,
348 metal_ancillaries->ift_local_single_hit_mblur,
353 metalrt_intersect.force_opacity((ray->self.prim ==
PRIM_NONE) ?
354 metal::raytracing::forced_opacity::opaque :
355 metal::raytracing::forced_opacity::non_opaque);
358 metal_ancillaries->blas_accel_structs[local_object].blas,
359 metal_ancillaries->ift_local_single_hit,
364 local_isect->num_hits = 0;
371 local_isect->num_hits = 1;
372 local_isect->hits[0].prim = prim;
373 local_isect->hits[0].type = prim_type;
374 local_isect->hits[0].object = local_object;
375 local_isect->hits[0].u =
intersection.triangle_barycentric_coord.x;
376 local_isect->hits[0].v =
intersection.triangle_barycentric_coord.y;
383 local_isect->Ng[0] =
normalize(
cross(tri_b - tri_a, tri_c - tri_a));
388 payload.
self_prim = ray->self.prim - primitive_id_offset;
396 metalrt_intersect.force_opacity(metal::raytracing::forced_opacity::non_opaque);
398# if defined(__METALRT_MOTION__)
401 payload.self_object = local_object;
403 metal_ancillaries->accel_struct,
406 metal_ancillaries->ift_local_mblur,
411 metal_ancillaries->blas_accel_structs[local_object].blas,
412 metal_ancillaries->ift_local,
426 const int num_hits = payload.
num_hits;
432 local_isect->num_hits = num_hits;
433 for (
int hit = 0; hit < num_hits; hit++) {
434 uint prim = payload.
hit_prim[hit] + primitive_id_offset;
435 local_isect->hits[hit].prim = prim;
436 local_isect->hits[hit].t = payload.
hit_t[hit];
437 local_isect->hits[hit].u = payload.
hit_u[hit];
438 local_isect->hits[hit].v = payload.
hit_v[hit];
439 local_isect->hits[hit].object = local_object;
440 local_isect->hits[hit].type = prim_type;
446 local_isect->Ng[hit] =
normalize(
cross(tri_b - tri_a, tri_c - tri_a));
454#ifdef __SHADOW_RECORD_ALL__
463 metal::raytracing::ray r(ray->P, ray->D, ray->tmin, ray->tmax);
464 metalrt_intersector_type metalrt_intersect;
465 metalrt_intersect.force_opacity(metal::raytracing::forced_opacity::non_opaque);
466 metalrt_intersect.assume_geometry_type(
467 metal::raytracing::geometry_type::triangle |
468 (
kernel_data.bvh.have_curves ? metal::raytracing::geometry_type::curve :
469 metal::raytracing::geometry_type::none) |
470 (
kernel_data.bvh.have_points ? metal::raytracing::geometry_type::bounding_box :
471 metal::raytracing::geometry_type::none));
474 payload.
self = ray->self;
482 typename metalrt_intersector_type::result_type
intersection;
484# if defined(__METALRT_MOTION__)
486 metal_ancillaries->accel_struct,
489 metal_ancillaries->ift_shadow_all,
493 r, metal_ancillaries->accel_struct, visibility, metal_ancillaries->ift_shadow_all, payload);
507 const uint visibility)
509 metal::raytracing::ray r(ray->P, ray->D, ray->tmin, ray->tmax);
510 metalrt_intersector_type metalrt_intersect;
511 metalrt_intersect.force_opacity(metal::raytracing::forced_opacity::non_opaque);
512 metalrt_intersect.set_geometry_cull_mode(metal::raytracing::geometry_cull_mode::bounding_box |
513 metal::raytracing::geometry_cull_mode::curve);
514 metalrt_intersect.assume_geometry_type(
515 metal::raytracing::geometry_type::triangle |
516 (
kernel_data.bvh.have_curves ? metal::raytracing::geometry_type::curve :
517 metal::raytracing::geometry_type::none) |
518 (
kernel_data.bvh.have_points ? metal::raytracing::geometry_type::bounding_box :
519 metal::raytracing::geometry_type::none));
522 payload.
self = ray->self;
524 typename metalrt_intersector_type::result_type
intersection;
526# if defined(__METALRT_MOTION__)
528 metal_ancillaries->accel_struct,
531 metal_ancillaries->ift_volume,
535 r, metal_ancillaries->accel_struct, visibility, metal_ancillaries->ift_volume, payload);
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
VecBase< float, 3 > float3
additional_info("compositor_sum_squared_difference_float_shared") .push_constant(Type output_img float dot(value.rgb, luminance_coefficients)") .define("LOAD(value)"
#define kernel_assert(cond)
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
#define ccl_device_forceinline
#define CCL_NAMESPACE_END
#define ccl_device_intersect
ccl_device_inline void bvh_instance_push(KernelGlobals kg, int object, ccl_private const Ray *ray, ccl_private float3 *P, ccl_private float3 *dir, ccl_private float3 *idir)
#define PRIMITIVE_UNPACK_SEGMENT(type)
@ SD_OBJECT_TRANSFORM_APPLIED
ccl_device_inline float cross(const float2 a, const float2 b)
Intersection< segment > intersection
IntegratorShadowStateCPU *ccl_restrict IntegratorShadowState
VecBase< float, 4 > float4
ccl_device_inline float3 float4_to_float3(const float4 a)
ccl_device_inline int clamp(int a, int mn, int mx)