ChunkMesher class
Face-culling, greedy mesher with baked ambient occlusion, sky + block light, liquids (lowered surface, own transparent surface), cross plants, torches, and the sub-block solids (slab, fence, stairs) built from axis-aligned boxes lit like cube faces. Works on a volume padded on every horizontal side, filled from the eight neighbour chunks, so a border face and its AO corners never guess.
The light is not baked into the vertex colour: the colour carries block tint × face tint × AO, and MeshSurface.light carries (sky / 15, block / 15). The two light volumes (chunk-sized) ride the result.
Cube and liquid faces are merged: coplanar neighbours of the same block, light, lowered top and AO corners become one quad, across a direction only where the AO does not change along it, so the interpolated colour is the one the unit faces had. What made every face different, the per-voxel colour variation, is not in the colour: a renderer computes it from the cell with voxelTint (voxel_scene's terrain shader does). Only the ChunkMeshResult.glow surface, meant for an unlit material, keeps it baked and its faces unmerged.
The padding is the whole 3×3 ring (48×48×128 cells), so the light flood sees every emitter within reach of this chunk and a torch beside a border lights both sides alike.
Its work buffers are static, so one set exists per isolate: build on one isolate at a time from one mesher, as a worker isolate does.
Constructors
- ChunkMesher({required Float32List palette, required Uint8List shape, required Uint8List opaque, required Uint8List emission, bool lighting = true})
-
A mesher over one block table's arrays, indexed by block id:
paletteholds four linear floats (rgba) per id,shapea BlockShape index,opaque1 where the id occludes faces and light,emission0..15. VoxelBlockTable.mesher builds one from a table.
Properties
- emission → Uint8List
-
The emitted light of every block id, 0..15.
final
- hashCode → int
-
The hash code for this object.
no setterinherited
- lighting → bool
-
False skips the light flood: skylight 15 everywhere, no block light. For
measuring what the light costs.
final
- palette → Float32List
-
Four floats per block id (rgba, linear).
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- shape → Uint8List
-
The BlockShape index of every block id.
final
Methods
-
build(
int chunkX, int chunkZ, List< Uint8List?> ring) → ChunkMeshResult -
Meshes chunk (
chunkX,chunkZ).ringis the chunk volume and its eight neighbours in ChunkStreamer.ring order (c, nx, px, nz, pz, nxnz, pxnz, nxpz, pxpz); a missing neighbour is null and reads as air. -
buildWith<
T> (int chunkX, int chunkZ, List< Uint8List?> ring, T use(ChunkMeshResult result)) → T -
Meshes chunk (
chunkX,chunkZ) as build does and hands the result touse, whose value it returns. That result's arrays are the mesher's own, valid only insideuse: read or copy them there. A worker that sends the mesh away copies it anyway, and so allocates no copy of its own. -
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited
Static Properties
- fullSkySeed ↔ bool
-
Tests only: seed the sky flood from every lit cell instead of only the
cells with a darker side neighbour. Both give the same light; this is the
slow reference the fast seeding is checked against.
getter/setter pair
Static Methods
Constants
- glowThreshold → const int
- A cube whose emission is at or above this goes on ChunkMeshResult.glow.
-
noNeighbours
→ const List<
Uint8List?> -
The eight neighbours of a chunk meshed alone:
[chunk, ...noNeighbours]. Every cell past its border reads as air. -
shapeIndices
→ const List<
int> -
The shape ints above in BlockShape order. They stay
constints, notBlockShape.indexreads, because they sit in the hottest loop; a test pins this list to the enum.