Skip to content

PRD-560: add height fog and fix native color grading - #482

Merged
jonit-dev merged 22 commits into
developfrom
feat/prd-560-height-fog
Oct 11, 2026
Merged

jonit-dev merged 22 commits into
developfrom
feat/prd-560-height-fog

Conversation

@jonit-dev

@jonit-dev jonit-dev commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Eleven templates previously gave low ground and high ridges the same distance-only haze. Their generated render source now integrates height fog, preserves the calibrated eye-level haze and colors the sun-facing horizon. The starter uses density 0.0021 with the integrated histogram exposure; the other kits retain their individually calibrated values. Mist retains sole ownership when enabled.

The native screenshot corruption was pre-existing: the original FogExp2 control also reproduced it. The native adapter advertised float32-filterable, but the device did not request it. Requesting that optional supported feature restores continuous color grading; a native regression assertion checks adapter/device agreement. A separate pre-existing puzzle visibility failure is corrected by changing only the authored cyan phase-material emission from 0.34 to 0.55.

PRD-560: all 8 phase boxes and all 3 acceptance criteria verified locally.

  • Starter: fog math, full canonical golden path, existing fourth fog scenario, mist arm and both ownership probes.
  • Native: current-density HUD/render-chain proof twice, 6/6 assertions each, fresh visual judgment IMPROVEMENT.
  • Remaining templates: complete canonical macros for action-rpg, minimal, puzzle, racing, rts, runner, sailing, shooter and snow; full platformer golden path. Shooter passes all 34 original scenarios, puzzle all 14 and platformer all 15.

Browser height-fog captures use three matched poses, two runs per arm, headed NVIDIA/Turing WebGPU. Fresh review finds overall IMPROVEMENT, including stronger ridge contrast while low ground stays hazier. The measured incremental GPU cost is +0.019 ms and −0.043 ms in two interleaved runs against the +0.1 ms budget; coarse readback supports the budget claim, not a speedup claim. Browser/native evidence.

Puzzle’s original lit probe passes 11/11 assertions twice with unchanged limits. Two fresh critics judge both pairs IMPROVEMENT; the busy overlap is pre-existing. Puzzle before/after evidence.

Validation: root typecheck and lint pass; 127 focused height-fog/template/scaffold tests pass. No scenario, assertion, viewport, timeout or performance budget was relaxed. The complete local pnpm test command remains red: the native suite lacks required local V8/QuickJS binaries and current dependency receipts, with consequent missing pump observations (23 failed, 1549 passed, 69 skipped in that suite). Fresh complete CI run 38152111029 now passes on candidate 6e165574fff67419cb91e421464234f18f4e4c44: 51 successful checks, 25 intentionally skipped checks, and ci-required SUCCESS. The native suite and selected native platform/integration jobs are qualified by that fresh run.

Limits: Pixel 8 cost remains deferred; no phone-performance or full native palette-parity claim. Existing native horizon speckle and the antialias Image is not defined limitation remain outside this correction.

Merge-queue qualification 38155269864 subsequently failed on the identical file tree. Unit shard 1 ran no tests after browser-dependency installation failed DNS resolution for archive.ubuntu.com. Native test steps passed; its compiled-tree cache-upload post-step failed. Unit shard 4 had one classifier import child-process failure (2207 passed, 17 skipped), and exposure cold boot observed 149/180 frames before its unchanged 60-second deadline. Receipt and required-check jobs rejected those failures. The PR remains unmerged while the harness paths are examined; no budget or assertion was relaxed.

One fresh full queue qualification was requested with the same pinned source after the DNS failure, native post-cache failure and passing 660 ms isolated import check. This is a new complete qualification, not a failed-job-only rerun. If cold boot repeats the same deadline failure, stop retries and investigate capture cadence with the original limits.

The single fresh queue retry 38159796759 failed different gates: unit shard 3 timed out in world-gpu-scene.spec.ts after 60 seconds (2640 passed, 16 skipped), and velocity integration exceeded its 22-second bridge advance deadline. The earlier DNS, import, native-cache and cold-boot failures did not repeat. The unchanged GPU-scene test passes in isolation locally in 36.7 seconds. Further blind queue retries are stopped while these harness paths are investigated; all original limits remain intact.

Closed-form exponential height fog on scene.fogNode, added to the distance term.
Mist ownership clears fogNode as well as fog.
heightFog.ts holds the closed-form maths and the TSL node, sky.ts the look numbers.
snow keeps its storm-driven FogExp2 as the distance term. Mist clears fogNode too.
…es (PRD-560)

The mist spec now covers scene.fogNode: the medium clears it with scene.fog, restores both
on dispose, and compose rejects a lingering fogNode. The eleven FogExp2 kits' parent
scaffold hashes follow their height-fog sources.
…RD-560)

Each kit's setupSky must keep its old FogExp2 transmittance at its eye-level distance within 2%.
Also reattach the racing and snow setupSky doc comments that the fog block had split from their
function, and refresh those two scaffold hashes.
… open

Phase 1 box 3: starter scenarios 4/4 on the height-fog arm and the mist arm,
one fog owner read at runtime. Phase 2: the owned desktop host passes 300
frames with height fog. Phase 3: eight template gates pass, the docs specs and
mirrors are in sync. AC-1a judged by a fresh judge, AC-2 delta -0.03 ms.
Open: AC-1b (ridge contrast judged unclear), shooter and platformer gates,
and the Pixel 8 check under Blocked on.
…p (PRD-560)

Develop moved the thirteen scaffold trees (Strata integration, shooter ADS
fix). The eleven FogExp2 kits carry height fog on top, so their createProject
fingerprints are re-measured by the spec that asserts them. Rain and
tower-defense keep develop's values.
@jonit-dev jonit-dev added the prd:75% PRD phases in, acceptance open label Oct 10, 2026
@jonit-dev

Copy link
Copy Markdown
Contributor Author

Before/after captures (PRD-560)

Same pose, same build settings, 1920x1080, headed, --browser-recipe webgpu, adapter nvidia/turing, two runs per arm. BEFORE/AFTER is burned into each image. Verdict from a fresh read-only judge: no regression in any pose; the ridge-versus-low-ground question was "unclear, leaning intended".

Default pose
default before r1
default after r1
default before r2
default after r2

High pose
high before r1
high after r1
high before r2
high after r2

Ridge pose (low slab left at 15 m, high slab right at 75 m, same distance)
ridge before r1
ridge after r1
ridge before r2
ridge after r2

Native desktop host (300 frames, non-blank)
native before
native after

Rejected attempts

  • Separate before/after builds for the AC-2 cost: unusable (host load 46, 2 to 7 fps, few windows). Replaced by a same-page scene.fogNode toggle.
  • First native run of both arms: TN_NATIVE_START_FAILED: location is not defined, caused by my scratch pose patch reading location in the native host. Guarded the patch and reran; the shipped templates are unaffected.
  • First play run of the mist arm: maxFrameMsP95 52.4 ms at host load near 30; passed twice at load below 13.
  • Template gate first runs on the RTX 2080: only maxFrameMsP95 (36.9 to 182.9 ms) plus one Xvfb start timeout, one dev-server unreachable and one GPU device-lost, with host load 20 to 47. Untouched tower-defense failed the same assertion (46.8 ms) and the base templates failed action-rpg and shooter there too.

@jonit-dev

Copy link
Copy Markdown
Contributor Author

PRD-560 AC-1b: second capture round, density: 0.0018

The first judge on density: 0.0012 read "unclear, leaning intended" on ridge versus low ground, which is NEUTRAL under the owner rule. Cause: the height term carried 60% of the kept eye-level haze, and the identical distance term hid the difference at 330 m (5 points of opacity). Seven kits (starter, minimal, platformer, action-rpg, runner, shooter, sailing) now carry about 84% of it in the height term.

Setup: starter scaffold, 1920x1080, headed, --browser-recipe webgpu, adapter nvidia / turing, two runs per arm per pose, interleaved. A fresh read-only judge saw all 12 frames.

Pose Verdict Note
default NEUTRAL same at normal viewing, no artefact
high NEUTRAL haze band very slightly greyer, no banding
ridge IMPROVEMENT raised cube clearly deeper red, ground cube lighter; "clearly visible, moderate, not dramatic"
overall IMPROVEMENT

Mean saturation of the low block vs the high block: 0.491 vs 0.603 after, 0.407 vs 0.404 before (first round at 0.0012: 0.461 vs 0.516).

Ridge pose, before then after (run 1):

before
after

All frames, density-0018-<pose>-<before|after>-r<1|2>.jpg on the prd-560-screenshots branch, for example:

The rejected 0.0012 frames stay on the branch as <pose>-<arm>-r<n>.jpg.

Existing comparisons reattached on 2026-10-10; these reuse the recorded prior fresh-judge verdict, with exact AFTER source verified against checkpoint b8874801b. No new judgment was run. Current 0.0018 browser cost/native rendering and template runtime gates remain incomplete; Pixel 8 cost remains blocked. PR stays draft for user inspection.

@jonit-dev jonit-dev added prd:50% PRD half the phases verified and removed prd:75% PRD phases in, acceptance open labels Oct 10, 2026
@jonit-dev

Copy link
Copy Markdown
Contributor Author

Source checkpoint 3f8e59100 is now on this draft PR and matches the attached density 0.0018 comparisons. No rebase or force push was used.

Scope correction: the historical starter gameplay/mist scenarios, browser GPU cost, and native desktop screenshot cover density 0.0012. Their current 0.0018 checks remain open; the twelve visual captures establish visual comparison only. The local follow-up PRD commit reopens the starter gameplay/mist box as well. Minimal/sailing current gates passed; action-rpg/runner failed and inherited shooter is still running. No runtime threshold was relaxed, and Pixel 8 cost remains blocked. Keep this PR draft for user inspection; final scaffold parent hash regeneration follows the eventual user-selected merge order.

@jonit-dev

Copy link
Copy Markdown
Contributor Author

Inherited template gate finished; this does not establish the current fog cost.

  • Minimal and sailing passed. Action-RPG and runner failed their runtime/performance checks, as previously recorded.
  • Shooter finished with failure: its test command exited 1; the boot capture exited 2 with TN_PLAYTEST_CAPTURE_PROVENANCE_MISSING (renderer kind could not be identified). No visual acceptance or performance conclusion follows from that capture.
  • Current runtime, native, and standalone cost requirements remain open. PR remains draft for inspection.

@jonit-dev
jonit-dev marked this pull request as ready for review October 11, 2026 07:37
…t-fog

# Conflicts:
#	packages/create-threenative/__tests__/scaffold.spec.ts
@jonit-dev jonit-dev added prd:25% PRD phase 1 verified and removed prd:50% PRD half the phases verified labels Oct 11, 2026
@jonit-dev

Copy link
Copy Markdown
Contributor Author

The native posterization was a pre-existing engine defect, also reproduced with the original FogExp2 control. The adapter offered float32-filterable, but device creation did not request it. Requesting the supported feature restores continuous sampling of the floating-point color-grading LUT.

Current combined candidate: four normal HUD-enabled desktop render-chain runs pass, two per arm, with grade applied in the final marker and zero diagnostics. A fresh independent visual judge returned IMPROVEMENT for both pairs and overall; geometry, shadows, camera framing and HUD layout are preserved.

BEFORE native run 1
AFTER native run 1

Independent second run

BEFORE native run 2
AFTER native run 2

Distant-floor dark speckling remains. Antialias still reports the pre-existing build:Image is not defined; this does not establish full browser/native parity. Browser height-fog visual acceptance remains open after the current judge returned NEUTRAL overall. CI currently needs native coverage regeneration; the two failures both report a stale source digest.

@jonit-dev jonit-dev added prd:50% PRD half the phases verified and removed prd:25% PRD phase 1 verified labels Oct 11, 2026
@jonit-dev

Copy link
Copy Markdown
Contributor Author

PR #482: starter height fog at density 0.0021

The images are pinned to commit 46e32ee8561950900dad8309847fad33b719553d on branch prd-560-screenshots, in folder pr482-final-0021/.

Verdicts

Native (native-render-chain, NVIDIA GeForce RTX 2080): IMPROVEMENT for pair 1, pair 2 and overall, from a read-only critic review of the four native frames. Clouds, material and blue highlights are smoother. Geometry, shadows and HUD align. A dark speckle remains at the horizon.

Browser (12 headed captures, 1920x1080, NVIDIA Turing): overall IMPROVEMENT. Ridge pose: IMPROVEMENT in both runs. Default and high poses: NEUTRAL. Verdicts are recorded under AC-1a in the PRD.

Images

Native before, from the historical .0018 source (not a same-run control):

Native before 1

Native before 2

Native after, from the .0021 source:

Native after 1

Native after 2

Browser before and after, two runs per arm. The before arm is the FogExp2 control. The after arm is height fog at 0.0021.

Browser default

Browser high

Browser ridge

Native runs

  • Two normal native runs, with the HUD on, passed. Each run exited 0 with pass: true, six of six assertions passing, and zero console and runtime diagnostics.
  • The grade stage reported graphOutputChanged: true in both runs.

Limitations

  • The native before frames are historical. They do not share a run with the after frames. The pair cannot attribute every visible change to the density change alone.
  • The native antialias path still fails with Image is not defined. This failure is pre-existing.
  • These results make no web and native parity claim and no cold-install claim.

Pending

  • AC-2, the template runtime gates and the root typecheck remain open.
  • The Pixel 8 phone-cost check remains open under ## Blocked on in the PRD.
  • This comment makes no merge claim.

@jonit-dev

Copy link
Copy Markdown
Contributor Author

Puzzle visibility correction: only the authored phase-material emissive multiplier changes from 0.34 to 0.55. Geometry, lights, opacity, edge cages and fog are unchanged. The original lit probe passes 11/11 assertions twice: dark-pixel ratios 0.47530 and 0.47417 against the unchanged 0.5 ceiling, NVIDIA/Turing, original 1280×720 viewport. The complete canonical puzzle macro subsequently passes all 14 scenarios.

Two fresh read-only judges return IMPROVEMENT for both pairs and overall. One notes the busy lattice; the second identifies the overlap as pre-existing, with no new or worsened artifact. Visual review alone does not establish physical playability. Banners preserve the original frame pixels.

Run 1 — BEFORE / AFTER

BEFORE 1

AFTER 1

Run 2 — BEFORE / AFTER

BEFORE 2

AFTER 2

@jonit-dev jonit-dev added prd:100% — ready PRD complete, ready to merge and removed prd:50% PRD half the phases verified labels Oct 11, 2026
@jonit-dev jonit-dev changed the title PRD-560: height fog follows the ground, and the sun shows through it PRD-560: add height fog and fix native color grading Oct 11, 2026
@jonit-dev
jonit-dev enabled auto-merge October 11, 2026 16:16
@jonit-dev
jonit-dev added this pull request to the merge queue Oct 11, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 11, 2026
@jonit-dev
jonit-dev added this pull request to the merge queue Oct 11, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 11, 2026
@jonit-dev
jonit-dev merged commit e6ed278 into develop Oct 11, 2026
76 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

prd:100% — ready PRD complete, ready to merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant