mirror of
https://github.com/blender/blender
synced 2026-10-25 03:07:01 +03:00
HIP-RT handles visibility at the TLAS instance level, and the motion triangle intersection was using software intersect that accesses the visibility flag, which is redundant. Curve and point primitives were fully relying on the instance visibility mask. The change allows to free the prim_visibility array once the BVH build is finished, to save up GPU memory. This is not done as part of this commit as there seems to be more arrays that are only needed during the build process. It would be easier to have a dedicated patch for this.
127 lines
4.6 KiB
C
127 lines
4.6 KiB
C
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 */
|
|
|
|
/* Motion Triangle Primitive
|
|
*
|
|
* These are stored as regular triangles, plus extra positions and normals at
|
|
* times other than the frame center. Computing the triangle vertex positions
|
|
* or normals at a given ray time is a matter of interpolation of the two steps
|
|
* between which the ray time lies.
|
|
*
|
|
* The extra positions are stored as additional motion steps in ATTR_STD_POSITION.
|
|
* Normals in ATTR_STD_VERTEX_NORMAL and ATTR_STD_CORNER_NORMAL.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "kernel/globals.h"
|
|
#include "kernel/types.h"
|
|
|
|
#include "kernel/geom/geom_intersect.h"
|
|
#include "kernel/geom/motion_triangle.h"
|
|
#include "kernel/geom/object.h"
|
|
|
|
#include "util/math_intersect.h"
|
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
/* Ray intersection. We simply compute the vertex positions at the given ray
|
|
* time and do a ray intersection with the resulting triangle.
|
|
*/
|
|
|
|
ccl_device_inline bool motion_triangle_intersect(KernelGlobals kg,
|
|
ccl_private Intersection *isect,
|
|
const float3 P,
|
|
const float3 dir,
|
|
const float tmin,
|
|
const float tmax,
|
|
const float time,
|
|
const uint visibility,
|
|
const int object,
|
|
const int prim,
|
|
const int prim_addr)
|
|
{
|
|
/* Get vertex locations for intersection. */
|
|
float3 verts[3];
|
|
motion_triangle_vertices(kg, object, prim, time, verts);
|
|
/* Ray-triangle intersection, unoptimized. */
|
|
float t;
|
|
float u;
|
|
float v;
|
|
if (ray_triangle_intersect(P, dir, tmin, tmax, verts[0], verts[1], verts[2], &u, &v, &t)) {
|
|
#if defined(__VISIBILITY_FLAG__) && !defined(__KERNEL_HIPRT__)
|
|
/* Visibility flag test. we do it here under the assumption that most triangles are culled by
|
|
* node flags.
|
|
* Note that HIP-RT performs visibility check on the instance level. */
|
|
if (kernel_data_fetch(prim_visibility, prim_addr) & visibility)
|
|
#endif
|
|
{
|
|
isect->t = t;
|
|
isect->u = u;
|
|
isect->v = v;
|
|
isect->prim = prim;
|
|
isect->object = object;
|
|
isect->type = PRIMITIVE_MOTION_TRIANGLE;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/* Special ray intersection routines for local intersections. In that case we
|
|
* only want to intersect with primitives in the same object, and if case of
|
|
* multiple hits we pick a single random primitive as the intersection point.
|
|
* Returns whether traversal should be stopped.
|
|
*/
|
|
#ifdef __BVH_LOCAL__
|
|
ccl_device_inline bool motion_triangle_intersect_local(KernelGlobals kg,
|
|
ccl_private LocalIntersection *local_isect,
|
|
const float3 P,
|
|
const float3 dir,
|
|
const float time,
|
|
const int object,
|
|
const int prim,
|
|
const float tmin,
|
|
const float tmax,
|
|
ccl_private uint *lcg_state,
|
|
const int max_hits)
|
|
{
|
|
/* Get vertex locations for intersection. */
|
|
float3 verts[3];
|
|
motion_triangle_vertices(kg, object, prim, time, verts);
|
|
/* Ray-triangle intersection, unoptimized. */
|
|
float t;
|
|
float u;
|
|
float v;
|
|
if (!ray_triangle_intersect(P, dir, tmin, tmax, verts[0], verts[1], verts[2], &u, &v, &t)) {
|
|
return false;
|
|
}
|
|
|
|
/* If no actual hit information is requested, just return here. */
|
|
if (max_hits == 0) {
|
|
return true;
|
|
}
|
|
|
|
const int hit_index = local_intersect_get_record_index(local_isect, t, lcg_state, max_hits);
|
|
if (hit_index == -1) {
|
|
return false;
|
|
}
|
|
|
|
/* Record intersection. */
|
|
ccl_private Intersection *isect = &local_isect->hits[hit_index];
|
|
isect->t = t;
|
|
isect->u = u;
|
|
isect->v = v;
|
|
isect->prim = prim;
|
|
isect->object = object;
|
|
isect->type = PRIMITIVE_MOTION_TRIANGLE;
|
|
|
|
/* Record geometric normal. */
|
|
local_isect->Ng[hit_index] = normalize(cross(verts[1] - verts[0], verts[2] - verts[0]));
|
|
|
|
return false;
|
|
}
|
|
#endif /* __BVH_LOCAL__ */
|
|
|
|
CCL_NAMESPACE_END
|