webgpu triangle
This commit is contained in:
parent
64116cd980
commit
5553ded476
22 changed files with 2107 additions and 42 deletions
|
|
@ -22,6 +22,7 @@ module;
|
|||
#include "vulkan/vulkan.h"
|
||||
#endif // !CRAFTER_GRAPHICS_WINDOW_DOM
|
||||
export module Crafter.Graphics:RenderingElement3D;
|
||||
import :RT;
|
||||
#ifndef CRAFTER_GRAPHICS_WINDOW_DOM
|
||||
import std;
|
||||
import :Mesh;
|
||||
|
|
@ -55,7 +56,7 @@ export namespace Crafter {
|
|||
|
||||
class RenderingElement3D {
|
||||
public:
|
||||
VkAccelerationStructureInstanceKHR instance;
|
||||
RTInstance instance;
|
||||
// Position in `elements`, maintained by Add/Remove for O(1) swap-and-pop.
|
||||
// Sentinel value = not currently registered.
|
||||
std::uint32_t indexInElements = std::numeric_limits<std::uint32_t>::max();
|
||||
|
|
@ -87,3 +88,63 @@ export namespace Crafter {
|
|||
};
|
||||
}
|
||||
#endif // !CRAFTER_GRAPHICS_WINDOW_DOM
|
||||
|
||||
#ifdef CRAFTER_GRAPHICS_WINDOW_DOM
|
||||
import std;
|
||||
import :Mesh;
|
||||
import :WebGPU;
|
||||
import :WebGPUBuffer;
|
||||
import :Window;
|
||||
|
||||
export namespace Crafter {
|
||||
// Per-frame TLAS storage. WebGPU has no real swapchain frame count
|
||||
// (Window::numFrames = 1 on DOM), so this is effectively a singleton —
|
||||
// the array form is kept for API symmetry with the Vulkan side so user
|
||||
// code that indexes `tlases[frameIdx]` ports unchanged.
|
||||
struct TlasWithBuffer {
|
||||
// Host-visible instance buffer holding RTInstance entries — same
|
||||
// layout as Vulkan's VkAccelerationStructureInstanceKHR, so user
|
||||
// code touching .instance.mask / .flags / .transform.matrix is
|
||||
// identical across backends. Also bound as a storage SSBO so
|
||||
// application compute shaders (e.g. physics-tlas-transform.comp.wgsl)
|
||||
// can write the .transform field directly when
|
||||
// RenderingElement3D::transformOwnedByGpu is set.
|
||||
WebGPUBuffer<RTInstance, true> instanceBuffer;
|
||||
// Per-instance application metadata; parallel to instanceBuffer,
|
||||
// identical semantics to the Vulkan-side counterpart.
|
||||
WebGPUBuffer<std::uint32_t, true> metadataBuffer;
|
||||
// GPU-built TLAS data: one TLASEntry per instance, written each
|
||||
// BuildTLAS by a compute pass on the JS bridge. Read by traceRay /
|
||||
// rayQuery as `@group(1) @binding(0) tlas: array<TLASEntry>`.
|
||||
// TLASEntry layout: 96 bytes — aabbMin (12) + maskHGoffset (4) +
|
||||
// aabbMax (12) + blasHandle (4) + invTransform 3x4 mat (48) +
|
||||
// customIndex (4) + _pad (12). Defined in the WGSL traversal
|
||||
// library; never directly read by C++.
|
||||
WebGPUBuffer<char, false> buffer;
|
||||
|
||||
std::uint32_t builtInstanceCount = 0;
|
||||
};
|
||||
|
||||
class RenderingElement3D {
|
||||
public:
|
||||
RTInstance instance{};
|
||||
std::uint32_t indexInElements = std::numeric_limits<std::uint32_t>::max();
|
||||
std::uint32_t userMetadata = 0;
|
||||
// Application compute shader writes the transform field of this
|
||||
// element's instanceBuffer slot directly — BuildTLAS preserves it.
|
||||
bool transformOwnedByGpu = false;
|
||||
|
||||
static std::vector<RenderingElement3D*> elements;
|
||||
inline static TlasWithBuffer tlases[Window::numFrames];
|
||||
|
||||
// Repopulate the TLAS for frame `index`. WebGPU path always does
|
||||
// a fresh build (no refit) — the GPU build pass is cheap at the
|
||||
// ~10–100 instance counts the design targets; LBVH-for-TLAS is a
|
||||
// future optimization for larger scenes.
|
||||
static void BuildTLAS(WebGPUCommandEncoderRef cmd, std::uint32_t index);
|
||||
|
||||
static void Add(RenderingElement3D* e);
|
||||
static void Remove(RenderingElement3D* e);
|
||||
};
|
||||
}
|
||||
#endif // CRAFTER_GRAPHICS_WINDOW_DOM
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue