trace from bounding box, not camera
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user