Regression test for the procedural BLAS path: the same 3x3x3 grid of unit-box AABBs runs through a PROCEDURAL_HIT_GROUP_KHR group whose GLSL intersection shader (reportIntersectionEXT) turns each box into a radius-1 sphere, the any-hit shader punches the spherical-checkerboard cut-out (visible proof non-opaque geometry runs any-hit), and the closest-hit shades per-instance tints — the WebGPU example behavior reproduced natively. Fixed camera in raygen.glsl; the WebGPU/DOM path is unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
32 lines
1.3 KiB
GLSL
32 lines
1.3 KiB
GLSL
#version 460
|
|
#extension GL_EXT_ray_tracing : enable
|
|
|
|
// RTVolume intersection shader — runs once per AABB the ray enters
|
|
// (VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR). Analytic
|
|
// ray-sphere test: the unit box [-1,1]^3 built by Mesh::BuildProcedural
|
|
// is treated as the bounding volume of a radius-1 sphere centred at the
|
|
// object origin. The object-space ray is NOT normalised (it is
|
|
// worldToObject * worldRay), so the reported t is directly comparable to
|
|
// the world-space ray parameter — solve the quadratic with the general
|
|
// a = dot(d,d) form rather than assuming |d| == 1. Mirrors
|
|
// intersection.wgsl on the WebGPU path.
|
|
|
|
hitAttributeEXT vec2 attribs;
|
|
|
|
void main() {
|
|
vec3 oc = gl_ObjectRayOriginEXT; // sphere centre is the origin
|
|
vec3 d = gl_ObjectRayDirectionEXT;
|
|
float a = dot(d, d);
|
|
float b = 2.0 * dot(oc, d);
|
|
float c = dot(oc, oc) - 1.0; // radius 1
|
|
float disc = b * b - 4.0 * a * c;
|
|
if (disc < 0.0) return;
|
|
|
|
float sq = sqrt(disc);
|
|
float t = (-b - sq) / (2.0 * a); // near root
|
|
if (t < gl_RayTminEXT) t = (-b + sq) / (2.0 * a); // fall back to far root
|
|
if (t < gl_RayTminEXT || t > gl_RayTmaxEXT) return;
|
|
|
|
attribs = vec2(0.0);
|
|
reportIntersectionEXT(t, 0u);
|
|
}
|