feat(webgpu-rt): emit intersection/any-hit dispatch + build AABB BVH
PipelineRTWebGPU emits a runIntersection mega-switch and the RT_HAS_ANYHIT / RT_HAS_INTERSECTION consts (+ the @CRAFTER_RT_TRACE_USER marker) that gate the library's new TRACE-stage user callbacks, so an opaque triangle-only scene still const-folds them away. Mesh-WebGPU builds a SAH BVH2 over AABB primitives and uploads them in primitive order for the intersection shader to fetch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
321fe596a7
commit
a91603c70b
2 changed files with 116 additions and 1 deletions
|
|
@ -213,6 +213,25 @@ namespace {
|
|||
nodes.emplace_back();
|
||||
BuildRecursive(0, 0, triCount);
|
||||
}
|
||||
|
||||
// AABB (procedural) geometry: one PrimRef per box, the box itself
|
||||
// is the primitive bound. The same SAH BVH2 then partitions them.
|
||||
void BuildFromAabbs(std::span<const RTAabb> aabbs) {
|
||||
std::uint32_t count = static_cast<std::uint32_t>(aabbs.size());
|
||||
prims.resize(count);
|
||||
for (std::uint32_t i = 0; i < count; ++i) {
|
||||
auto& pr = prims[i];
|
||||
pr.box.Extend(aabbs[i].min);
|
||||
pr.box.Extend(aabbs[i].max);
|
||||
pr.centroid[0] = (pr.box.lo[0] + pr.box.hi[0]) * 0.5f;
|
||||
pr.centroid[1] = (pr.box.lo[1] + pr.box.hi[1]) * 0.5f;
|
||||
pr.centroid[2] = (pr.box.lo[2] + pr.box.hi[2]) * 0.5f;
|
||||
pr.triIndex = i;
|
||||
}
|
||||
nodes.reserve(count * 2);
|
||||
nodes.emplace_back();
|
||||
BuildRecursive(0, 0, count);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -243,7 +262,10 @@ namespace {
|
|||
indices.data(), static_cast<std::int32_t>(indices.size()),
|
||||
builder.nodes.data(), static_cast<std::int32_t>(builder.nodes.size()),
|
||||
primRemap.data(), static_cast<std::int32_t>(primRemap.size()),
|
||||
attribsBytes.data(), static_cast<std::int32_t>(attribsBytes.size()));
|
||||
attribsBytes.data(), static_cast<std::int32_t>(attribsBytes.size()),
|
||||
/*geomType*/ 0,
|
||||
/*opaqueFlag*/ mesh.opaque ? 1 : 0,
|
||||
/*primCount*/ static_cast<std::int32_t>(mesh.triangleCount));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -273,3 +295,43 @@ void Mesh::Build(const CompressedMeshAsset& asset,
|
|||
|
||||
BuildBVHAndRegister(*this, vertices, indices, std::span(dataBytes));
|
||||
}
|
||||
|
||||
void Mesh::BuildProcedural(std::span<const RTAabb> aabbs,
|
||||
bool opaque_,
|
||||
WebGPUCommandEncoderRef /*cmd*/) {
|
||||
const std::uint32_t count = static_cast<std::uint32_t>(aabbs.size());
|
||||
opaque = opaque_;
|
||||
triangleCount = 0; // not a triangle mesh
|
||||
vertexCount = count * 2; // 2 "vertices" (min,max) per box
|
||||
|
||||
Builder builder;
|
||||
builder.BuildFromAabbs(aabbs);
|
||||
|
||||
// The AABB stream is uploaded in *original* primitive order (2 vec3 per
|
||||
// box). primRemap maps each BVH leaf slot back to its original index, so
|
||||
// the intersection shader's _rtFetchAabb(meshRec, primId) reads the
|
||||
// right box — exactly mirroring how the triangle path indexes vertices.
|
||||
std::vector<Vector<float, 3, 3>> boxVerts(count * 2);
|
||||
for (std::uint32_t i = 0; i < count; ++i) {
|
||||
boxVerts[i*2 + 0] = Vector<float, 3, 3>{ aabbs[i].min[0], aabbs[i].min[1], aabbs[i].min[2] };
|
||||
boxVerts[i*2 + 1] = Vector<float, 3, 3>{ aabbs[i].max[0], aabbs[i].max[1], aabbs[i].max[2] };
|
||||
}
|
||||
|
||||
std::vector<std::uint32_t> primRemap(count);
|
||||
for (std::uint32_t i = 0; i < count; ++i) {
|
||||
primRemap[i] = builder.prims[i].triIndex;
|
||||
}
|
||||
|
||||
const BVHNode& root = builder.nodes[0];
|
||||
blasAddr = WebGPU::wgpuRegisterMeshBLAS(
|
||||
root.aabbMin[0], root.aabbMin[1], root.aabbMin[2],
|
||||
root.aabbMax[0], root.aabbMax[1], root.aabbMax[2],
|
||||
boxVerts.data(), static_cast<std::int32_t>(boxVerts.size()),
|
||||
nullptr, 0,
|
||||
builder.nodes.data(), static_cast<std::int32_t>(builder.nodes.size()),
|
||||
primRemap.data(), static_cast<std::int32_t>(primRemap.size()),
|
||||
nullptr, 0,
|
||||
/*geomType*/ 1,
|
||||
/*opaqueFlag*/ opaque ? 1 : 0,
|
||||
/*primCount*/ static_cast<std::int32_t>(count));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue