trace from bounding box, not camera

This commit is contained in:
2026-02-17 21:38:19 +00:00
parent 19b72dbc67
commit 0e6f188de7
+50 -9
View File
@@ -8,27 +8,68 @@ const float EPSILON = .001;
const uint MAX_STEPS = 50;
// axis aligned, center at the origin, dimensions "box_size"
// https://iquilezles.org/articles/intersectors/
vec2 box_intersection(in vec3 ro, in vec3 rd, vec3 box_size)
{
vec3 m = 1.0 / rd; // can precompute if traversing a set of aligned boxes
vec3 n = m * ro; // can precompute if traversing a set of aligned boxes
vec3 k = abs(m) * box_size;
vec3 t1 = -n - k;
vec3 t2 = -n + k;
float tN = max(max(t1.x, t1.y), t1.z);
float tF = min(min(t2.x, t2.y), t2.z);
if (tN > tF || tF < 0.0) return vec2(-1.0); // no intersection
return vec2(tN, tF);
}
void main() {
if (SPEC_BOUNDING_BOXES) {
reportIntersectionEXT(gl_RayTminEXT, 0);
return;
}
Object object = objects.objects[gl_InstanceID];
vec3 internal_pos = vec3(
float((gl_PrimitiveID >> (object.subdivision_log2 * 2)) & ((1 << object.subdivision_log2) - 1))
/ float(1 << object.subdivision_log2),
float((gl_PrimitiveID >> (object.subdivision_log2 * 1)) & ((1 << object.subdivision_log2) - 1))
/ float(1 << object.subdivision_log2),
float((gl_PrimitiveID >> (object.subdivision_log2 * 0)) & ((1 << object.subdivision_log2) - 1))
/ float(1 << object.subdivision_log2)
);
vec3 low_corner = (((vec3(0.0) / float(1 << object.subdivision_log2)) + internal_pos)
* object.dimensions) + object.lowest_corner;
vec3 high_corner = (((vec3(1.0) / float(1 << object.subdivision_log2)) + internal_pos)
* object.dimensions) + object.lowest_corner;
vec3 raypos = gl_ObjectRayOriginEXT;
vec3 raydir = gl_ObjectRayDirectionEXT;
float farplane = gl_RayTmaxEXT;
vec3 adjusted_raypos = raypos - ((high_corner + low_corner) / 2.0);
vec3 dimensions = high_corner - low_corner;
vec3 p = raypos;
float total_dist = gl_RayTminEXT;
vec2 near_far = box_intersection(adjusted_raypos, raydir, dimensions);
if (near_far.x < 0.) {
return;
}
float near_plane = near_far.x;
float far_plane = near_far.y;
if (SPEC_BOUNDING_BOXES) {
reportIntersectionEXT(near_plane, 0);
return;
}
float total_dist = near_plane;
vec3 p = fma(raydir, vec3(total_dist), raypos);
for (uint i = 0; i < MAX_STEPS; i++) {
float dist = scene(vec4(p, camera_uniforms.campos_and_time.w));
total_dist += dist;
p = fma(raydir, vec3(total_dist), raypos);
if (abs(dist) < EPSILON) {
reportIntersectionEXT(max(total_dist, gl_RayTminEXT), 0);
reportIntersectionEXT(max(total_dist, near_plane), 0);
return;
} else if (total_dist > farplane) {
} else if (total_dist > far_plane) {
break;
}
}