73 lines
4.6 KiB
Markdown
73 lines
4.6 KiB
Markdown
# Terrain Authoring
|
||
|
||
Terrain is a first-class authored actor backed by `TerrainDesc`. Add it from the Inspector's
|
||
**Add Component** shelf by searching for Terrain. It conflicts with other geometry sources on the
|
||
same actor: Primitive, Brush, Static Mesh Renderer, and Skinned Mesh Renderer.
|
||
|
||
## Foundation Workflow
|
||
|
||
The Terrain card exposes grid resolution, sample spacing, height scale, chunk size, generated
|
||
collision, shadows, base material status, and validation. **Resize Flat** deliberately replaces the
|
||
height array with a flat grid; normal numeric edits retain all height samples. Every accepted edit is
|
||
one reflected history transaction and rebuilds only that terrain's generated chunks.
|
||
|
||
## Sculpt Workflow
|
||
|
||
Select a terrain actor and enable the mountains button in the existing horizontal viewport toolbar.
|
||
Choose **Raise**, **Lower**, **Flatten**, **Smooth**, or **Noise**, then LMB-drag across the terrain.
|
||
The radius and strength controls use world meters; the colored footprint follows the sampled terrain
|
||
surface and identifies the active mode.
|
||
|
||
Each drag is one stroke and one undo entry, regardless of how many interpolated dabs it contains.
|
||
Escape or right-click restores the exact pre-stroke height grid; when no stroke is active, either input
|
||
closes the sculpt tool. Flatten captures the height under the initial press. Smooth samples a stable
|
||
copy of the current neighborhood per dab, and Noise uses a deterministic per-stroke seed so authored
|
||
results remain reproducible.
|
||
|
||
## Material Layers And Paint Workflow
|
||
|
||
The Terrain card owns up to four shared Material or Material Instance layers. Use the plus icon to
|
||
add a channel, then browse or drag a material into its selector. Each layer exposes independent UV
|
||
tiling and can be reordered or removed; channel weights move with the layer. The first added layer
|
||
adopts a legacy Base Material assignment so existing terrain converts without visual loss.
|
||
|
||
With at least two layers assigned, select the paint-brush button beside Sculpt in the existing
|
||
horizontal viewport toolbar. Choose **Paint** or **Erase**, select the target layer, then LMB-drag.
|
||
Paint increases the selected channel while proportionally reducing the others; Erase redistributes
|
||
weight to the remaining channels. Every sample stays normalized to 255, the terrain-following cyan
|
||
or amber footprint previews the brush, and release records one undo entry. Escape or right-click
|
||
restores the exact pre-stroke weights or closes the idle tool.
|
||
|
||
`assets/levels/terrain_authoring_showcase.scn.ron` is the Terrain entry in the deterministic
|
||
[sample regression pack](sample-regression-pack.md). Its 5×5
|
||
grid forms an asymmetric hill split into four 2×2-quad chunks. It validates chunk boundaries,
|
||
normals, selection through generated children, collider generation, inspector state, and save
|
||
stripping. Height geometry is inline, while its committed shared Material and Material Instance
|
||
references deliberately validate terrain dependency resolution and layer transport.
|
||
|
||
## Data And Hydration
|
||
|
||
- Heights are finite normalized values multiplied by Height Scale at hydration time.
|
||
- Up to four Material/Material Instance references remain shared assets rather than copied material
|
||
descriptors. RGBA8 weights are stored per height sample; an absent array means full layer zero.
|
||
- Generated chunk vertex colors carry normalized weights into the `blacksite_surface` terrain
|
||
material, which blends layer base color/texture, normal, metallic, and roughness inputs.
|
||
- Sample Spacing controls X/Z distance and the grid remains centered on the actor origin.
|
||
- Chunk Size is measured in quads. Neighboring chunks share boundary samples but not runtime mesh
|
||
assets, allowing later stroke updates to rebuild only affected chunks.
|
||
- Missing, unassigned, or invalid layer references produce a clear diagnostic and visible terrain
|
||
fallback rather than missing geometry.
|
||
- Generated `HydratedTerrainChunk` children own mesh, optional trimesh collider, and shadow state.
|
||
They are runtime-only and never serialized as authored actors.
|
||
- Foundation chunks are explicitly excluded from Solari submission and force their layer blend
|
||
through Bevy's forward opaque raster path while Auto/Solari is active. Raster material-layer
|
||
parity is shipped; matching Solari terrain evaluation remains explicit future work, and the editor
|
||
never substitutes a semantically different proxy.
|
||
|
||
The terrain foundation is recorded in [ADR 0039](../adr/0039-inline-height-grid-terrain-foundation.md),
|
||
and layer weight persistence/render transport in
|
||
[ADR 0040](../adr/0040-terrain-material-layer-weights.md).
|
||
|
||
Live native-Wayland evidence and focused verification are recorded in the
|
||
[terrain foundation evaluation](evaluations/terrain-foundation/).
|