Builtin Library
- ..
- .metadata17 B
- README.md3.0 KB
- greedy.wgsl13.7 KB
- init.luau28.3 KB
README.md
gpu
GPU greedy mesher. Dispatches a WGSL compute shader that emits vertices
and indices directly into GPU-resident storage buffers; the caller wraps
those buffers with renderer.mesh.create for a zero-copy renderable mesh.
Mirrors the CPU mesher's public API surface so the top-level backend
selector (Mesher.setBackend / Mesher.build) can swap CPU ↔ GPU without
the caller caring which one produced the mesh descriptor.
The mesher runs the package's greedy_mesh.computeShader, which declares the
six buffers it binds and takes the engine's vertex stride as a param. It is
resolved and compiled on first use of M.build; later calls reuse it.
Exports
M.isAvailable() -> boolean— probe whether the engine exposes the compute + mesh-from-buffer globals.M.build(opts: BuildOpts) -> MeshDescriptor— dispatch the greedy mesher shader. Output'sgpuBuffersis what you pass torenderer.mesh.create.M.releaseBuffers(desc: MeshDescriptor?)— destroy the GPU buffers owned by a descriptor. Must be called when the mesh is no longer needed.
Types:
Vec3 = { x: number, y: number, z: number }Submesh = { material: string, indexStart: number, indexCount: number }GpuBuffers = { vertex: string, index: string, counters?: string, vertexCount: number, indexCount: number }Aabb = { min: Vec3, max: Vec3 }MeshDescriptor = { positions, indices, normals, uvs, colors, submeshes, vertexCount, gpuBuffers?, aabb }BuildOpts = { size, blockSize?, origin?, isSolid, getColor, getMaterial? }
Usage
local Gpu = require("@builtin::systems.voxelEngine.voxelEngine.mesher.gpu")
if Gpu.isAvailable() then
local desc = Gpu.build({
size = { x = 32, y = 32, z = 32 },
blockSize = 1.0,
isSolid = function(x, y, z) return ... end,
getColor = function(x, y, z) return r, g, b end,
})
-- Pass desc.gpuBuffers.vertex / .index into renderer.mesh.create.
-- When the mesh is no longer needed:
Gpu.releaseBuffers(desc)
end
Notes
- Grid dimensions are capped at 64 per axis (matches the shader's
MAX_SIZEworkgroup-memory layout —MAX_SIZE * MAX_SIZE * 4u32 mask bytes fit the WebGPU baselinemaxComputeWorkgroupStorageSizeof 16 KiB). Larger grids must be split into chunks before meshing. - Face emission order differs from the CPU mesher (
+Y, -Y, +X, -X, +Z, -Zvs CPU's+X, -X, +Y, -Y, +Z, -Z); vertex indexing is internally consistent within each mesh. vertexCountand the index count reported ingpuBuffers.indexCountare conservative upper bounds — unused slots collapse to degenerate triangles. This matches howrenderer.mesh.createwraps the buffers.- Multi-material parity with the CPU mesher is approximate; see the in-file TODO for the planned shader extension.
releaseBuffersis mandatory on completion. Forgetting it leaks GPU memory because the buffers stay alive for the lifetime of the mesh.