Builtin Library
- ..
- .metadata17 B
- README.md2.6 KB
- gpu.module
- init.luau20.7 KB
README.md
mesher
Pure-function voxel mesher. Walks a grid via isSolid, getColor, and
optional getMaterial callbacks and emits CPU-side mesh data (positions,
indices, normals, uvs, colors, submeshes). Two CPU variants — buildSimple
(one quad per visible face) and buildGreedy (merges adjacent faces of the
same color and material) — plus a generic build that dispatches through
a session-level backend selector (CPU or GPU).
Submesh index convention is 0-based: submeshes[i].indexStart is the
offset into indices where material i's faces begin, counted from 0.
This matches GPU draw-call conventions. Even a single-material mesh gets a
submesh entry — callers never have to branch on its presence.
The GPU backend lives in the sibling gpu.module/. The selector defaults
to "gpu" when the engine exposes compute + renderer.mesh.create,
and "cpu" otherwise.
Exports
M.buildSimple(opts: BuildOpts) -> MeshDescriptor— one quad per visible face. CPU-only.M.buildGreedy(opts: BuildOpts) -> MeshDescriptor— greedy face merging, per-material passes. CPU-only.M.setBackend(name: BackendName)— set the session-default backend ("cpu"or"gpu"). Raises on unknown names.M.getBackend() -> BackendName— read the current default. Resolves lazily on first call.M.build(opts: BuildOpts) -> MeshDescriptor— dispatch through the active backend.
Types:
Vec3 = { x: number, y: number, z: number }Submesh = { material: string, indexStart: number, indexCount: number }MeshDescriptor = { positions, indices, normals, uvs, colors, submeshes, vertexCount, gpuBuffers?, aabb? }BuildOpts = { size: Vec3, blockSize?: number, origin?: Vec3, isSolid, getColor, getMaterial? }BackendName = "cpu" | "gpu"
Usage
local Mesher = require("@builtin::systems.voxelEngine.voxelEngine.mesher")
local desc = Mesher.buildGreedy({
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,
})
-- Or via the backend selector:
Mesher.setBackend("gpu")
local desc = Mesher.build(opts)
Notes
- CCW-front winding. Output is ready for
renderer.mesh.create(CPU) orrenderer.mesh.create(GPU). - An empty mesh (no visible faces) yields an empty
submeshesarray. buildSimple/buildGreedyare direct CPU entry points — they bypass the backend selector. Use them when you need CPU-side vertex arrays even if the session default is GPU.setBackendonly affectsbuild— explicit calls tobuildSimple/buildGreedyalways run CPU.