trace from bounding box, not camera
This commit is contained in:
@@ -8,27 +8,68 @@ const float EPSILON = .001;
|
|||||||
|
|
||||||
const uint MAX_STEPS = 50;
|
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() {
|
void main() {
|
||||||
if (SPEC_BOUNDING_BOXES) {
|
Object object = objects.objects[gl_InstanceID];
|
||||||
reportIntersectionEXT(gl_RayTminEXT, 0);
|
|
||||||
return;
|
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 raypos = gl_ObjectRayOriginEXT;
|
||||||
vec3 raydir = gl_ObjectRayDirectionEXT;
|
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;
|
vec2 near_far = box_intersection(adjusted_raypos, raydir, dimensions);
|
||||||
float total_dist = gl_RayTminEXT;
|
|
||||||
|
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++) {
|
for (uint i = 0; i < MAX_STEPS; i++) {
|
||||||
float dist = scene(vec4(p, camera_uniforms.campos_and_time.w));
|
float dist = scene(vec4(p, camera_uniforms.campos_and_time.w));
|
||||||
total_dist += dist;
|
total_dist += dist;
|
||||||
p = fma(raydir, vec3(total_dist), raypos);
|
p = fma(raydir, vec3(total_dist), raypos);
|
||||||
if (abs(dist) < EPSILON) {
|
if (abs(dist) < EPSILON) {
|
||||||
reportIntersectionEXT(max(total_dist, gl_RayTminEXT), 0);
|
reportIntersectionEXT(max(total_dist, near_plane), 0);
|
||||||
return;
|
return;
|
||||||
} else if (total_dist > farplane) {
|
} else if (total_dist > far_plane) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user