BlueGit

golden-age paperdoll-renderer

design: RGB band depth uses export bit depth (16-bit RGBA, depth_bits) (t981u)

timfa Grok Bot · pushed by timfa

Authored 2026-11-07 · 7 days ago

Hash
cc95e2e7b0475f9d11f5483821f0774e0e9c3b2b
Parent
a1800952
Pipeline
Passed
1 file changed +2 −2
design.md +2 −2
@@ -405,6 +405,6 @@ 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): optional RGB band depth encoding
408 ## Decision 2026-11-07 (Tim t980u, amended t981u): optional RGB band depth 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 **8-bit RGBA "bands"**: with `t = (d − near)/(far − near)` clamped to 0..1, `v = round(t·765)`, `R = min(v, 255)`, `G = clamp(v − 255, 0, 255)`, `B = clamp(v − 510, 0, 255)`; decode `v = R + G + B`, `d = near + (v/765)·(far − near)`. This gives 766 levels; alpha is kept. The encoding is recorded in `render.json` and in the `.ppda` (`depth_encoding` value plus a boolean `depth_rgb_bands`), so the game renderer and the 2D previewer decode it correctly; the previewer/compositor support both encodings. Older `.ppda` files without the boolean are read as gray16. The setting is part of the render contract (changing it is a contract difference for resume).
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).
@@ -405,6 +405,6 @@ Exports no longer pile up as `renders/run-<id>/` folders. Each result lives in `
405
405
406Implementation (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.
406Implementation (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): optional RGB band depth encoding
408## Decision 2026-11-07 (Tim t980u, amended t981u): optional RGB band depth encoding
409
409
410A 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 **8-bit RGBA "bands"**: with `t = (d − near)/(far − near)` clamped to 0..1, `v = round(t·765)`, `R = min(v, 255)`, `G = clamp(v − 255, 0, 255)`, `B = clamp(v − 510, 0, 255)`; decode `v = R + G + B`, `d = near + (v/765)·(far − near)`. This gives 766 levels; alpha is kept. The encoding is recorded in `render.json` and in the `.ppda` (`depth_encoding` value plus a boolean `depth_rgb_bands`), so the game renderer and the 2D previewer decode it correctly; the previewer/compositor support both encodings. Older `.ppda` files without the boolean are read as gray16. The setting is part of the render contract (changing it is a contract difference for resume).
410A 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).