render3d: a README note on painted ground layers, and the changeset
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
54e267dfa6
commit
530956889b
2 changed files with 48 additions and 0 deletions
35
packages/ludic.render3d/README.md
Normal file
35
packages/ludic.render3d/README.md
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
# ludic.render3d
|
||||
|
||||
A physically based 3D renderer over Vulkan. `FEATURES.md` lists what is implemented and where.
|
||||
|
||||
## Painted ground layers
|
||||
|
||||
A ground layer is a density painted over the map (R the chance a cell keeps one, G its scale, 2 m texels
|
||||
baked into an LGD2 file, `ground_density.ludic`) and a `GroundFill` row of numbers. Everything it grows is
|
||||
a pure function of those two - the same on every machine and in the editor's preview.
|
||||
|
||||
- **The candidate** (`ground_cand.ludic`): for (layer, chunk, band, cell) `ground_candidate` answers
|
||||
whether one stands there and its x, z, scale, yaw, seed and wind, into a `GroundCand` the caller holds.
|
||||
Its steps are pure: `gf_along` (the jitter, draws 0 and 1), `gf_keeps` (draw 2 under the chance),
|
||||
`gf_scale` (G and draw 6), `gf_yaw` (3), `gf_seed` (4), `gf_wind` (5). `ground_fill` draws exactly
|
||||
these. Numbers are IEEE single precision, `Math.lerp` is `a + (b - a) * t`, `gf_hash` is 32-bit
|
||||
integer arithmetic with a logical `>>`, and the model shader turns local (x, z) to
|
||||
`(c x + s z, -s x + c z)` - three.js's rotation about +Y.
|
||||
- **Cover and solid.** A cover layer (grass, flowers, pebbles) is filled at its band's step, so a far
|
||||
band is a different, sparser sample. A layer with `solid: true` (rocks, trees) is filled at `step0`
|
||||
with band 0's hashes whatever the band, and a far band draws the subset whose draw 7 falls under
|
||||
`(step0 / step_band)^2`; its scale ignores `band_grow`. Nothing solid moves with the camera.
|
||||
- **Solid ids** (`ground_solid.ludic`): `ground_solid_id(layer, cx, cz, i, j, cells)` =
|
||||
`((layer * 256 + cz + 128) * 256 + cx + 128) * 512 + i * cells + j`, a positive 31-bit int, stable
|
||||
while the painting under it is. It holds chunks -128 .. 127 about the stream's corner and at most 22
|
||||
cells a chunk side (a step of at least 32 / 22 m on 32 m chunks); a cell past that has no id and is
|
||||
not grown. `ground_solid_list` fills a caller's `GroundSolids` (made once, `ground_solids_new`) with a
|
||||
chunk's things for physics, the nav bake or a save; `ground_solid_at` answers one by id.
|
||||
- **The trample as data** (`ground_clear.ludic`): `r3d_ground_clearing(x, z, r_in, r_out, floor)` hands
|
||||
over a clearing - `floor` inside `r_in`, back to full at `r_out` on a smoothstep, the shape of the
|
||||
camp's ring and the town's yard. A layer with `trample` multiplies its chance by the game's callback
|
||||
(`r3d_on_ground_trample`, kept for now) and then by every clearing. A game should use one or the other.
|
||||
- **Conformance**: `tests/ground_fill_test.ludic` holds the package to `tests/ground_fill_golden.json`
|
||||
(gf_hash, lerp, yaw, one cover chunk and one solid chunk over a hand-written density), which the
|
||||
studio's own test reads. After a deliberate change, rebuild it from the repository root:
|
||||
`bin/ludic run packages/ludic.render3d/tests/gen/ground_fill_golden.ludic --headless`, and commit it.
|
||||
Loading…
Add table
Add a link
Reference in a new issue