Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,15 @@ still to land.
a fixed frame; one tilemap renders in a bounded number of draw
calls — one per (texture, material, blend) group) (M2-TILE-01;
FR-2.6).
- [Parallax layers](api/parallax.md) —
`laige::render::ParallaxLayers<Backend>`: the named
background/midground/foreground layer model (M2-PAR-01; FR-2.3):
the parallax factor (0..1), the EXACT world-space offset formula
`factor * (p - center) + offset`, the UV scroll (auto or manual)
with the exact wrap at the texture boundary (rendered through the
2 x 2 wrap split into the sprite batcher), and the documented
background-first render order (the depth-key layer values:
background -2, midground -1, ground 0, foreground +1).

## Guides

Expand Down
10 changes: 8 additions & 2 deletions docs/api/iso_depth_key.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,12 @@ uint32_t isoDepthKey(sim::SimMath<Backend>::Vec2 pos,
units (the tile map's per-tile height, M2-TILE-01). *Not* the
object's own sprite height.
- **`layer`** — the render layer (`kIsoDepthGroundLayer` = 0 default;
the parallax layer values land with M2-PAR-01 — background layers
negative/sorted first, foreground positive/sorted last).
the parallax layer values are documented, M2-PAR-01,
[`parallax.md`](parallax.md) — the presets are
`kParallaxDepthLayerBackground` = -2 (sorted first),
`kParallaxDepthLayerMidground` = -1,
`kParallaxDepthLayerForeground` = +1 (sorted last); a custom layer
picks any value in the domain [-512, +511]).

**The formula** (world space only — never screen space, PRD §4):

Expand Down Expand Up @@ -192,5 +196,7 @@ if (posOk.ok()) {
shear contract is pinned against (M2-GL-03).
- [`presentation.md`](presentation.md) — the interpolated positions the
key reads (M1-LOOP-02).
- [`parallax.md`](parallax.md) — the parallax layer values that use
the key's layer field (M2-PAR-01).
- Roadmap: M2-ISO-01 (this), M2-ISO-02 (key table), M2-SORT-01 (stable
radix sort), M2-SPRITE-01/02 (batcher), M2-PAR-01 (layer values).
5 changes: 4 additions & 1 deletion docs/api/iso_depth_table.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ The per-sprite key this table precomputes is
addressing shift/mask, division-free), `maxChunks` (default
`kIsoDepthTableDefaultMaxChunks` = 1024; the growth cap), `layer`
(default `kIsoDepthGroundLayer` = 0 — a parallax tile LAYER gets its
own table with its layer value, M2-PAR-01).
own table with its layer value, M2-PAR-01 — the values are
documented in [`parallax.md`](parallax.md)).

### The cell model

Expand Down Expand Up @@ -244,6 +245,8 @@ if (table.value().covers(gx, gy)) {
gate's harness.
- [baselines/m2-iso-depth-table.md](../benchmarks/baselines/m2-iso-depth-table.md)
— the recorded 10k-dirty-cell baseline.
- [`parallax.md`](parallax.md) — the parallax layer values that use
the table's layer (M2-PAR-01).
- Roadmap: M2-ISO-02 (this), M2-TILE-01 (tilemap wiring), M2-SORT-01
(stable radix sort), M2-SPRITE-01/02 (batcher), M2-PAR-01 (layer
values).
302 changes: 302 additions & 0 deletions docs/api/parallax.md

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion docs/api/tilemap.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ duplicated validation): `originTileX/Y` (default 0), `widthTiles` /
`kIsoDepthTableChunkTiles` = 16; a power of two ≥ 1), `maxChunks`
(default `kIsoDepthTableDefaultMaxChunks` = 1024), `layer` (default
`kIsoDepthGroundLayer` = 0 — a parallax tile LAYER gets its own
tilemap with its layer value, M2-PAR-01). `TileData` is a plain value
tilemap with its layer value, M2-PAR-01 — the values are documented
in [`parallax.md`](parallax.md)). `TileData` is a plain value
(8 B of data + the table's height — the value the game writes on
load/edit and reads back).

Expand Down
62 changes: 58 additions & 4 deletions docs/concepts/coordinates.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ The render order is the lexicographic tuple **(key, entity id)**:

1. **key** (this step, M2-ISO-01): layer ascending as the coarse
primary order (background layers first — the parallax layer values
land with M2-PAR-01), then the quantized depth;
are documented, M2-PAR-01, §4.10), then the quantized depth;
2. **entity id**: equal keys keep the deterministic insertion order —
the stable sort (M2-SORT-01) preserves it and the batcher
(M2-SPRITE-01) inserts in the engine's deterministic entity-id
Expand Down Expand Up @@ -337,6 +337,53 @@ The scene's static tile grid is
draw call per chunk group); the count is a function of the distinct
group keys, never of the tile count.

### 4.10 The parallax layers: the named background/midground/foreground model (M2-PAR-01)

The scene's parallax layers are
`laige::render::ParallaxLayers<Backend>`
(`laige/render/parallax.h`) — the named bg/mid/fg model of FR-2.3,
declared into the batcher of §4.7 (S-5) with the §4.1 keys:

- **The offset formula** (world space only — PRD §4, RENDER-006): a
layer's content position at camera position `p` (the camera's
ground-plane (x, y), the M2-CAM-01 presentation position) is
`worldOffset(p) = factor * (p - center) + offset` — the EXACT
formula (the tests pin it bit-exactly for dyadic values).
`factor` in [0, 1]: 0 = fixed in world space (maximum parallax, a
close-by background), 1 = fixed on screen (no parallax, the sky
layer); `center` = the reference camera position (default the world
origin); `offset` = the world-space offset at `p = center`.
- **The depth layer values** (the §4.1 layer field, engine-owned —
G-R11): `kParallaxDepthLayerBackground` = -2 (the `bg` preset),
`kParallaxDepthLayerMidground` = -1 (the `mid` preset),
`kIsoDepthGroundLayer` = 0 (the ground),
`kParallaxDepthLayerForeground` = +1 (the `fg` preset); a custom
layer picks any value in the M2-ISO-01 domain [-512, +511]
(more negative = further back).
- **Background first** (the documented render order): WITHIN a shared
(atlas, material, blend) group the layer field dominates the key —
every background-layer quad sorts before every ground object and
every foreground quad after it, whatever the quads' v
(engine-guaranteed, the §4.1 "layer dominates" contract). ACROSS
groups the draw order is the batcher's group order (ascending
(atlas, material, blend), §4.7) — the scene's SET-UP assigns the
parallax layers' atlas ids so the group order matches the depth
order: background ids BELOW the world content's, foreground ids
ABOVE it (the M2-TILE-01 texture-id convention).
- **The UV scroll** (auto or manual): each layer carries a CURRENT UV
OFFSET in [0, 1)²; Auto advances it by `scrollSpeed` (UV units PER
FRAME) on `advanceScrolls()` — once per frame, before the
declarations — and the wrap is EXACT at the texture boundary
(`wrap(x) = x - floor(x)`: 1.0 → exactly 0.0). A scrolled layer
renders through the 2 x 2 wrap split (up to four quads — one
SpriteItem carries one UV rect, no wrap); the quad's key is the
§4.1 key of the quad's world center at the layer's `depthLayer`.
- **Tilemap-source layers** (the M2-TILE-02 hook): a layer's
`source = Tilemap` declares its tilemap's tiles with this layer's
`worldOffset` translation and `depthLayer` (the tilemap's
`Options::layer`, §4.9); in M2-PAR-01 they are DATA ONLY
(`declareTo` skips them).

## 5. Conversion rules (the module boundaries, RENDER-006)

| Conversion | Direction | Owner | Status |
Expand All @@ -348,6 +395,7 @@ The scene's static tile grid is
| World → screen (render) | sim state → NDC → pixels | camera + preset matrix (M2-CAM-01/02, M2-GL-03), `ProjectionView::worldToScreen` (M2-PROJ-01), sprite draw (M2-SPRITE-02) | **Shipped** (matrices + camera core M2-CAM-01, iso presets + grid-snap M2-CAM-02, world→screen transform M2-PROJ-01, pixels: `SpriteRenderer::submit`'s offscreen instanced draw M2-SPRITE-02) |
| Atlas frame → UV sub-rect | animation frame index + sheet layout → UV rect | `laige-render` (`spriteFrameUv`, M2-SPRITE-03) | **Shipped (M2-SPRITE-03)** |
| Tile grid → static tile quads | tile data + table keys → declared sprites (fixed-frame quads) | `laige-render` (`TileMap::declareTo`, M2-TILE-01) | **Shipped (M2-TILE-01)** |
| Camera position → parallax offset | camera (x, y) + layer def → world-space offset (the exact formula) + wrap quads | `laige-render` (`ParallaxLayers::worldOffsetAt` / `declareTo`, M2-PAR-01) | **Shipped (M2-PAR-01)** |

### 5.1 The isometric grid picking (M2-ISO-03)

Expand Down Expand Up @@ -422,9 +470,11 @@ For one isometric frame, objects render in ascending
batcher (M2-SPRITE-01) and drawn by the sprite renderer (M2-SPRITE-02)
through the engine's stable depth sort (`DepthSort`, §4.6,
M2-SORT-01).
Parallax layers (M2-PAR-01) render background-first via their layer
values; the UI pass (M2-UI-02) is a separate screen-space pass rendered
after all world passes. Determinism of the order is total: same world
Parallax layers (M2-PAR-01, §4.10) render background-first via their
depth-layer values (the layer field dominates within a group; the
scene's atlas-id convention orders the groups); the UI pass
(M2-UI-02) is a separate screen-space pass rendered after all world
passes. Determinism of the order is total: same world
state → same keys → same order, every frame (RENDER-003).

## Related
Expand All @@ -451,6 +501,10 @@ state → same keys → same order, every frame (RENDER-003).
- [`api/tilemap.md`](../api/tilemap.md) — the tilemap contract:
`TileMap` (chunked tile grid + the auto-depth wiring of the depth
table + the static tile-quad batch path) (M2-TILE-01).
- [`api/parallax.md`](../api/parallax.md) — the parallax layer
contract: `ParallaxLayers` (the named bg/mid/fg model — the offset
formula, the depth-layer values, the UV scroll + exact wrap, the
2 x 2 wrap-split batch path) (M2-PAR-01).
- [`api/matrices.md`](../api/matrices.md) — the matrix builders and NDC
conventions (M2-GL-03).
- [`decisions/0005-iso-default.md`](../decisions/0005-iso-default.md) —
Expand Down
Loading
Loading