design: depth_bits 8 (default)/16 x gray/rgb-bands, four encodings (t983u)
@@ -405,6 +405,9 @@ Exports no longer pile up as `renders/run-<id>/` folders. Each result lives in `
405
405
406
406
Implementation (2026-11-07): the build folder is `renders/inprogress-<stamp>-<pid>-<sex>-<settype>/` (the only resumable kind). After `complete.json` the run is re-validated with `AtlasSet::open_run`, its lock released, the old result renamed to `.replaced-<name>-<stamp>`, the build renamed to `<sex>-<settype>-atlas`, then the old one removed (restored if the rename fails). `resume::recover` runs before every render: a `.replaced-*` folder is restored when its result folder is missing (else removed), and a completed, unlocked, validating `inprogress-*` folder is promoted. The 2D preview only opens `*-atlas` folders whose name matches their `.ppda` sex/settype; `run-*` folders are skipped with a notice; `inprogress-*`/`.replaced-*` are ignored silently.
407
407
408
## Decision 2026-11-07 (Tim t980u, amended t981u): optional RGB band depth encoding
408
## Decision 2026-11-07 (Tim t980u, amended t981u/t983u): depth bit depth + optional RGB band encoding
409
409
410
A boolean project setting in `.ppd`, `depth_rgb_bands`, default **off**. Off: depth is exported as today (16-bit gray+alpha, `distance = near + (gray/65535)·(far−near)`). On: the depth map is exported as RGB "bands" **at the export's bit depth** (currently 16-bit, so M = 65535): with `t = (d − near)/(far − near)` clamped to 0..1, `v = round(t·3M)`, `R = min(v, M)`, `G = clamp(v − M, 0, M)`, `B = clamp(v − 2M, 0, M)`; output is a **16-bit RGBA PNG** with alpha kept. Decode `v = R + G + B`, `d = near + (v/3M)·(far − near)` (3M+1 levels). The encoding and bit depth are recorded in `render.json` and in the `.ppda` (`depth_encoding` plus `depth_bits`, and the boolean `depth_rgb_bands`), so the game renderer and the 2D previewer decode either form; the previewer/compositor support both. Older `.ppda` files without these fields are read as gray16. The setting is part of the render contract (changing it is a contract difference for resume).
410
Two project settings in `.ppd`: `depth_bits` = **8 (default)** or 16, and the boolean `depth_rgb_bands`, default **off**. This changes the default export: depth becomes 8-bit unless 16 is chosen. Four combinations, with M = 2^bits − 1 (255 or 65535) and `t = (d − near)/(far − near)` clamped to 0..1:
411
- `gray8` (default) / `gray16`: gray+alpha PNG at that bit depth, `gray = round(t·M)`, decode `d = near + (gray/M)·(far − near)`.
412
- `rgb-bands8` / `rgb-bands16`: RGBA PNG at that bit depth, `v = round(t·3M)`, `R = min(v, M)`, `G = clamp(v − M, 0, M)`, `B = clamp(v − 2M, 0, M)`, alpha kept; decode `v = R + G + B`, `d = near + (v/3M)·(far − near)` (3M+1 levels; 766 at 8-bit).
413
`render.json` and the `.ppda` record `depth_bits` and `depth_encoding` (`gray` or `rgb-bands`), so the game renderer and the 2D previewer decode all four; the previewer/compositor support all four. Older `.ppda` files without `depth_bits` are read as gray16 (their actual format). Both settings are part of the render contract (changing them is a contract difference for resume).
@@ -405,6 +405,9 @@ Exports no longer pile up as `renders/run-<id>/` folders. Each result lives in `405
405
406
Implementation (2026-11-07): the build folder is `renders/inprogress-<stamp>-<pid>-<sex>-<settype>/` (the only resumable kind). After `complete.json` the run is re-validated with `AtlasSet::open_run`, its lock released, the old result renamed to `.replaced-<name>-<stamp>`, the build renamed to `<sex>-<settype>-atlas`, then the old one removed (restored if the rename fails). `resume::recover` runs before every render: a `.replaced-*` folder is restored when its result folder is missing (else removed), and a completed, unlocked, validating `inprogress-*` folder is promoted. The 2D preview only opens `*-atlas` folders whose name matches their `.ppda` sex/settype; `run-*` folders are skipped with a notice; `inprogress-*`/`.replaced-*` are ignored silently.406
Implementation (2026-11-07): the build folder is `renders/inprogress-<stamp>-<pid>-<sex>-<settype>/` (the only resumable kind). After `complete.json` the run is re-validated with `AtlasSet::open_run`, its lock released, the old result renamed to `.replaced-<name>-<stamp>`, the build renamed to `<sex>-<settype>-atlas`, then the old one removed (restored if the rename fails). `resume::recover` runs before every render: a `.replaced-*` folder is restored when its result folder is missing (else removed), and a completed, unlocked, validating `inprogress-*` folder is promoted. The 2D preview only opens `*-atlas` folders whose name matches their `.ppda` sex/settype; `run-*` folders are skipped with a notice; `inprogress-*`/`.replaced-*` are ignored silently.407
407
408
## Decision 2026-11-07 (Tim t980u, amended t981u): optional RGB band depth encoding408
## Decision 2026-11-07 (Tim t980u, amended t981u/t983u): depth bit depth + optional RGB band encoding409
409
410
A boolean project setting in `.ppd`, `depth_rgb_bands`, default **off**. Off: depth is exported as today (16-bit gray+alpha, `distance = near + (gray/65535)·(far−near)`). On: the depth map is exported as RGB "bands" **at the export's bit depth** (currently 16-bit, so M = 65535): with `t = (d − near)/(far − near)` clamped to 0..1, `v = round(t·3M)`, `R = min(v, M)`, `G = clamp(v − M, 0, M)`, `B = clamp(v − 2M, 0, M)`; output is a **16-bit RGBA PNG** with alpha kept. Decode `v = R + G + B`, `d = near + (v/3M)·(far − near)` (3M+1 levels). The encoding and bit depth are recorded in `render.json` and in the `.ppda` (`depth_encoding` plus `depth_bits`, and the boolean `depth_rgb_bands`), so the game renderer and the 2D previewer decode either form; the previewer/compositor support both. Older `.ppda` files without these fields are read as gray16. The setting is part of the render contract (changing it is a contract difference for resume).410
Two project settings in `.ppd`: `depth_bits` = **8 (default)** or 16, and the boolean `depth_rgb_bands`, default **off**. This changes the default export: depth becomes 8-bit unless 16 is chosen. Four combinations, with M = 2^bits − 1 (255 or 65535) and `t = (d − near)/(far − near)` clamped to 0..1:411
- `gray8` (default) / `gray16`: gray+alpha PNG at that bit depth, `gray = round(t·M)`, decode `d = near + (gray/M)·(far − near)`.412
- `rgb-bands8` / `rgb-bands16`: RGBA PNG at that bit depth, `v = round(t·3M)`, `R = min(v, M)`, `G = clamp(v − M, 0, M)`, `B = clamp(v − 2M, 0, M)`, alpha kept; decode `v = R + G + B`, `d = near + (v/3M)·(far − near)` (3M+1 levels; 766 at 8-bit).413
`render.json` and the `.ppda` record `depth_bits` and `depth_encoding` (`gray` or `rgb-bands`), so the game renderer and the 2D previewer decode all four; the previewer/compositor support all four. Older `.ppda` files without `depth_bits` are read as gray16 (their actual format). Both settings are part of the render contract (changing them is a contract difference for resume).