Builtin Library
- ..
- README.md3.1 KB
- mat.yaml1.4 KB
- preview.png2.3 KB
README.md
terrainSplat (material)
The eight-layer terrain surface. Blends three layer atlases — albedo, normal, mask — by the two RGBA weight textures the landscape was baked with.
You normally do not apply this material yourself
terrainSurface.forLandscape(data) instances it per landscape: the
.terrainData's control textures bound as the weight maps, its rect as
field_min / field_size, its packed sheets as the three atlases, and its
layer table as the per-layer tints and tilings. What you apply is the handle
that call returns — and a Terrain component does even that for you.
This asset is the same shader with defaults, so it is inspectable and it is what a hand-authored variant starts from. Applied by hand it has no weight textures and no field rect, so it renders layer 0 everywhere — an unbound stack looks unbound rather than looking broken.
Properties
| Property | Unit | What it does |
|---|---|---|
field_min, field_size | metres | the rect the weight textures cover; zero size means no weight map |
weights_lo_data, weights_hi_data | — | layers 0-3 and 4-7, normalised to sum to one |
layer_atlas_albedo / _normal / _mask | — | 4x2 atlases, layer N at (N mod 4, N div 4) |
atlas_size | texels | atlas dimensions, for the half-texel inset between cells |
layerN_tint | — | multiplies layer N's albedo sample |
layerN_size | metres | world metres one repeat of layer N's texture covers |
weight_sharpen | — | 1 is the stack as evaluated; higher narrows every transition without moving it |
height_blend | — | 0 blends by weight alone; higher gives a contested pixel to whichever layer's mask height stands proudest |
normal_strength | — | scales the blended tangent-space XY; 0 is flat |
smoothness, metallic | — | scale the mask atlas's alpha and red |
The mask atlas
Each cell is a mask MAP in the usual channel order: R metallic, G ambient
occlusion, B height, A smoothness. White is the neutral one — no occlusion, a
level height that leaves height_blend with nothing to reorder, and metallic
and smoothness left to the two scalars.
The height channel is what makes a transition look like two materials meeting
rather than a crossfade: where the weights call a tie, height_blend gives the
pixel to the layer standing proudest there, so sand settles into the gaps
between cobbles instead of fading evenly across their faces. Layers at equal
height are attenuated equally, so a white atlas comes through unchanged.
Three atlases, not twenty-four slots
A slot per layer per map would put twenty-four sampled textures in one bind
group, which is past what WebGPU guarantees a shader stage. The atlas keeps the
cost at three whatever the layer count is. terrain.write packs the sheets when
it bakes a landscape — a layer names its own albedo / normal / mask
textures and they are resampled into that layer's cell — so the packing is not
something an author does by hand.
A stack with no atlas at all renders its eight layerN_tint colours, which is
enough to see every rule working.