// rayQuery picking smoke test (WebGPU/DOM software ray-query path). // // Shoots a single, fully-determined ray at a known TLAS instance through // the injected `rayQuery*` shim and records the committed hit into a // storage buffer the host reads back. The whole point is to exercise // `_rqTraverseTlas`'s TLAS descent for a realistic (< 8193) instance // count — the regime where a hardcoded 16384-leaf start makes every node // look internal and the pick always misses (issue #25). // // rayQuery=true ⇒ @group(1) is the reserved RT heap (do NOT declare it). // User bindings live at @group(2)+; the optional push uniform at @group(0). struct PushData { origin: vec3, _p0: f32, dir: vec3, _p1: f32, }; @group(0) @binding(0) var push : PushData; struct PickResult { hit: u32, // 1 = committed triangle hit, 0 = miss instanceCustomIndex: u32, primitiveIndex: u32, tHit: f32, }; @group(2) @binding(0) var result : PickResult; @compute @workgroup_size(1) fn main() { var rq: RayQuery; rayQueryInitialize(&rq, 0u, RT_FLAG_OPAQUE, 0xFFu, push.origin, 0.001, push.dir, 10000.0); // Software shim resolves the whole traversal in one proceed call. while (rayQueryProceed(&rq)) {} if (rayQueryGetCommittedIntersectionType(&rq) != RT_INTERSECTION_NONE) { result.hit = 1u; result.instanceCustomIndex = rayQueryGetCommittedInstanceCustomIndex(&rq); result.primitiveIndex = rayQueryGetCommittedPrimitiveIndex(&rq); result.tHit = rayQueryGetCommittedT(&rq); } else { result.hit = 0u; result.instanceCustomIndex = 0xFFFFFFFFu; result.primitiveIndex = 0xFFFFFFFFu; result.tHit = -1.0; } }