LOCATION(n) for vertex inputs and GPU_D3D11 or GPU_D3D12, whichever the
overlay runs on.
Camera
Binddevice.frame.camera to a GPU_CAMERA and read it like a struct:
The camera includes the game’s TAA jitter, so your draws line up with the engine’s. Don’t declare
the matrices
row_major: mul(M, v) is already the right product.
Spaces and depth
frame.sceneDepth, worldDepth and solidDepth hold post-projection depth, 0 near and 1 far,
cleared to 1. It’s the same value SV_Position.z has in your own draws.
Draw parameters
D3D startsSV_VertexID and SV_InstanceID at 0 for every draw. WebGPU’s numbering includes the
draw’s first vertex (or base vertex) and first instance. To get it in HLSL:
register(b0, space4) is reserved for this. WGSL doesn’t need it.
Poses
Every player skinned this frame, from theopaque hook on. pass.drawPose binds them as vertex
buffers; bound as read-only storage, you read them yourself.
Pose positions end up in scene space: project with
camera.sceneViewProj, or convert with
GpuSceneToGame.
Models
Whatdevice.importModel loads: 80 bytes per vertex, bind pose, game space.
GpuLoadModelVertex(buffer, index) reads one from a storage buffer. As a vertex buffer, use the
model’s vertexLayout.
Map
frame.worldVertices is float3 positions in scene space, frame.worldIndices is a uint32 triangle
list. They are vertex and index buffers; copy them into a buffer of your own to read them in a compute
shader.
Smokes
GPU_SMOKE_VOXEL_HALF (60, 60, 30) around its center, and they
overlap a lot: treat them as “smoke is somewhere around here”, not as the cloud’s exact shape.
GpuLoadSmokeVoxel(smokeVoxels, index) and GpuLoadSmoke(smokeTable, cloud) read them.
In WGSL: