webgpu sponza
This commit is contained in:
parent
5553ded476
commit
b5d0f52da0
21 changed files with 1426 additions and 58 deletions
|
|
@ -19,6 +19,7 @@ module Crafter.Graphics:Mesh_implWebGPU;
|
|||
|
||||
import :Mesh;
|
||||
import :WebGPU;
|
||||
import Crafter.Asset;
|
||||
import Crafter.Math;
|
||||
import std;
|
||||
|
||||
|
|
@ -215,26 +216,59 @@ namespace {
|
|||
};
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Shared between the positions-only and the compressed-asset Build paths.
|
||||
// attribsBytes is empty for positions-only meshes; the JS bridge skips
|
||||
// the attribs-heap append in that case.
|
||||
void BuildBVHAndRegister(Mesh& mesh,
|
||||
std::span<const Vector<float, 3, 3>> vertices,
|
||||
std::span<const std::uint32_t> indices,
|
||||
std::span<const std::byte> attribsBytes) {
|
||||
mesh.triangleCount = static_cast<std::uint32_t>(indices.size()) / 3;
|
||||
|
||||
Builder builder;
|
||||
builder.Build(vertices, indices);
|
||||
|
||||
std::vector<std::uint32_t> primRemap(mesh.triangleCount);
|
||||
for (std::uint32_t i = 0; i < mesh.triangleCount; ++i) {
|
||||
primRemap[i] = builder.prims[i].triIndex;
|
||||
}
|
||||
|
||||
const BVHNode& root = builder.nodes[0];
|
||||
mesh.blasAddr = WebGPU::wgpuRegisterMeshBLAS(
|
||||
root.aabbMin[0], root.aabbMin[1], root.aabbMin[2],
|
||||
root.aabbMax[0], root.aabbMax[1], root.aabbMax[2],
|
||||
vertices.data(), static_cast<std::int32_t>(vertices.size()),
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
||||
void Mesh::Build(std::span<Vector<float, 3, 3>> vertices,
|
||||
std::span<std::uint32_t> indices,
|
||||
WebGPUCommandEncoderRef /*cmd*/) {
|
||||
triangleCount = static_cast<std::uint32_t>(indices.size()) / 3;
|
||||
BuildBVHAndRegister(*this, vertices, indices, {});
|
||||
}
|
||||
|
||||
Builder builder;
|
||||
builder.Build(vertices, indices);
|
||||
void Mesh::Build(const CompressedMeshAsset& asset,
|
||||
WebGPUCommandEncoderRef /*cmd*/) {
|
||||
std::vector<Vector<float, 3, 3>> vertices(asset.vertexCount);
|
||||
std::vector<std::uint32_t> indices(asset.indexCount);
|
||||
std::vector<std::byte> dataBytes(
|
||||
static_cast<std::size_t>(asset.dataCount) * asset.dataStride);
|
||||
|
||||
std::vector<std::uint32_t> primRemap(triangleCount);
|
||||
for (std::uint32_t i = 0; i < triangleCount; ++i) {
|
||||
primRemap[i] = builder.prims[i].triIndex;
|
||||
}
|
||||
// CompressedBlob always carries 3 regions for MeshAsset (the data region
|
||||
// can have decompressedSize=0). DecompressCPU validates output sizes
|
||||
// against region sizes, so the empty-data path needs the empty span.
|
||||
std::array<std::span<std::byte>, 3> outputs = {
|
||||
std::as_writable_bytes(std::span(vertices)),
|
||||
std::as_writable_bytes(std::span(indices)),
|
||||
std::span<std::byte>(dataBytes),
|
||||
};
|
||||
Compression::DecompressCPU(asset.blob,
|
||||
std::span(outputs).first(asset.blob.regions.size()));
|
||||
|
||||
const BVHNode& root = builder.nodes[0];
|
||||
std::uint32_t h = WebGPU::wgpuRegisterMeshBLAS(
|
||||
root.aabbMin[0], root.aabbMin[1], root.aabbMin[2],
|
||||
root.aabbMax[0], root.aabbMax[1], root.aabbMax[2],
|
||||
vertices.data(), static_cast<std::int32_t>(vertices.size()),
|
||||
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()));
|
||||
blasAddr = h;
|
||||
BuildBVHAndRegister(*this, vertices, indices, std::span(dataBytes));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue