diff --git a/docs/PRDs/batch-2026-10-01-visual-quality/EXECUTE.md b/docs/PRDs/batch-2026-10-01-visual-quality/EXECUTE.md new file mode 100644 index 0000000000..17a273b524 --- /dev/null +++ b/docs/PRDs/batch-2026-10-01-visual-quality/EXECUTE.md @@ -0,0 +1,53 @@ +# Execute this batch + +## Agent handoff + +```text +Read AGENTS.md, docs/PRDs/AGENTS.md and this folder's README.md. +Work from current origin/develop in an isolated branch/worktree. +Choose the highest-value unblocked item from the execution queue. +For an existing owner, read and update its canonical PRD rather than writing a replacement. +Reconcile the current code, tests and merged/open PRs before treating any older claim as missing. +Search capabilities and inspect the installed Three pin and its patches before adding a system. +Keep appearance in generated game source. Reuse the renderer, mixer, loader and frame lifecycle. +Open one implementation PR for that PRD, not one PR for this entire implementation batch. +Implement the smallest bounded phase, run its named tests and playtest, and update actual results inline. +Do not tick another platform's box from browser proof or a green metadata/build check. +Rebase/reconcile shared files between dependent tasks; do not merge parallel changes blindly. +Stop at a failed admission gate with the measured reason, or complete/archive the PRD honestly. +``` + +## Proof setup + +Each new PRD names future test/scenario paths. Those paths are not claimed to exist today. Add the smallest opt-in fixture to the existing `examples/abyss-framework` example, or reuse a better existing fixture and change the proof path in the canonical PRD. Its normal scene must remain unchanged. Do not create a new engine package merely to hold an example. + +`VQ_URL` must point to the built/served fixture. `VQ_NATIVE_EXECUTABLE` must name that same fixture's packaged Linux executable. `VQ_ANDROID_DEVICE` is the chosen online emulator/device serial for VQ-01. Build/serve/package using the repository's existing commands; variables with `:?` deliberately refuse an unset value. Capture the fixture route, exact cohort/commit and adapter with the result. Do not run a scenario against an unrelated default scene and report success. + +For new public mechanisms, use the existing capability manifest/MCP and update generated guidance. Inspect the installed pin (`three@0.185.1` at the audit baseline) before using an addon seen in online documentation. An incompatible addon can be declined, scoped down, or introduced through an explicitly qualified upgrade; none licenses an automatic fork of the renderer. + +## Checks and progress + +Run `pnpm prd:progress ` before work and after each phase. New specs have three phases, six phase boxes and two acceptance boxes, with `proof:` on each. All start at zero; a written plan is not implementation progress. Existing PRDs may need their old checklist shape repaired **without deleting completed work**. + +For implementation, use the root AGENTS.md runtime gates and the exact feature playtests. For this documentation-only collection, use the repository's prose lane: + +```sh +pnpm check:docs +pnpm exec vitest run scripts/__tests__/check-doc-links.spec.ts scripts/__tests__/evidence-budget.spec.ts scripts/__tests__/evidence-citations.spec.ts scripts/__tests__/sync-agent-docs.spec.ts scripts/__tests__/ci-structure.spec.ts scripts/__tests__/ci-needs.spec.ts +``` + +Those commands are required execution guidance, not a claim they were run while filing this collection. No runtime test, new benchmark result or human visual approval is supplied by this planning change. + +## Concurrency and shared ownership + +| Workstream | Can proceed independently | Serialize or reconcile | +|---|---|---| +| Build/runtime correctness | VQ-01 | Runtime artifact capability contract and loader/cook changes | +| Native output correctness | VQ-02 | `renderer.ts`, output attachments and native replay | +| Temporal/exposure | PRD-269, then PRD-455; PRD-339 after output is reliable | `chain.ts`, `velocity.ts`, `worldEnvironment.ts`, quality source | +| Animation | VQ-04 followed by VQ-05 | One mixer/action owner; do not let both reset action weights | +| World transitions | PRD-460, then proxy/impostor follow-ups | CPU and GPU WorldCells selection, per-instance identity, shadow alpha | +| Lighting | VQ-03 and upstream admission for VQ-06 | Material lighting contribution, probe capture budgets and PRD-457 | +| Optional look work | Decals and material fixture authoring | Shared generated render plumbing and temporal/alpha semantics | + +Hardware access, rights to assets and human aesthetic approval are named blockers, not progress boxes. Browser and Linux-native qualification is not a promise of phone frame rate. Release scope is unchanged; this folder does not declare all visual experiments release-critical. diff --git a/docs/PRDs/batch-2026-10-01-visual-quality/EXISTING-PRDS.md b/docs/PRDs/batch-2026-10-01-visual-quality/EXISTING-PRDS.md new file mode 100644 index 0000000000..48a86d9185 --- /dev/null +++ b/docs/PRDs/batch-2026-10-01-visual-quality/EXISTING-PRDS.md @@ -0,0 +1,43 @@ +# Existing canonical PRDs in this batch + +These are **references to existing work, not duplicate specifications**. Their files, evidence, completed boxes and associated PRs stay at their canonical paths. This preserves history and in-flight branches while providing one execution entry point. + +Baseline inspected: `d72778382b134ef8763f58825cb4d4fd8cc0f6e3` on `develop`. Old status prose is not authoritative over newer code. Before execution, compare the relevant implementation and tests, preserve all proved work, add only the unresolved scope and normalize missing per-phase/proof markers in the canonical document. Never turn a stale `PROPOSED` heading into a rewrite order. + +| Queue | Owner | Outcome | Execution note | Dependency / coordination | +|---|---|---|---|---| +| Wave 0 | [PRD-269](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/lighting/PRD-269-motion-vectors-or-the-temporal-filters-lie.md) | Velocity/history correctness | Source exists; reconcile old PROPOSED text with current velocity code. Qualify gaps; do not rebuild it. | Before 455, VQ-13 and temporal hair/fog consumers. | +| Wave 1 | [PRD-455](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/unreal-like-features/PRD-455-temporal-reconstruction-from-dynamic-resolution.md) | Temporal AA and dynamic-resolution reconstruction | Reuse existing owner. Same-resolution temporal qualification is its first bounded milestone; an upstream TRAA node is not by itself an upscaler. | 269; coordinate MSAA, jitter, camera cuts and instance identity. | +| Wave 1 | [PRD-339](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/AAA-visuals/PRD-339-the-frame-sets-its-own-exposure.md) | Auto exposure / eye adaptation | Reuse; adapt the current generated-source exposure seam, not a second tone mapper. | VQ-02 output correctness; include dark/bright transition traces. | +| Wave 1 | [PRD-460](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/unreal-like-features/PRD-460-invisible-streaming-transitions.md) | Prop arrival and LOD crossfades | Reuse; terrain morphing already exists. Apply the remaining work to CPU and GPU-selected scatter routes. | Existing WorldCells and PR #375; coordinate temporal reactive/disocclusion behavior. | +| Wave 2 | [PRD-456](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/unreal-like-features/PRD-456-distant-world-cell-proxies.md) | Distant cell HLOD / silhouettes | Reuse; do not confuse per-asset impostors or shadow proxies with cell HLOD. | Existing world-resource accounting; 460 handoffs. | +| Wave 2 | [PRD-457](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/unreal-like-features/PRD-457-virtual-shadows-scale-by-measurement.md) | Shadow scheduling, sparse-page admission, local-light boundary | Reuse. Directional virtual shadows already exist; phase 3 also owns local-light work. | Coordinate VQ-06; preserve a correct cached-level fallback. | +| Wave 2 | [PRD-344](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/AAA-visuals/PRD-344-contact-occlusion-baked-from-the-geometry-it-ships-with.md) | Cheap baked contact occlusion | Reuse; distinguish this outcome from existing lightmaps and imported AO textures. | Use current cook/mesh data; retain mobile low-tier benefit. | +| Wave 2 | [PRD-268](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/lighting/PRD-268-light-that-comes-from-off-screen.md) | Static diffuse probes / off-screen lighting | Source exists; reconcile implementation and remaining proof before any extension. | Precondition for VQ-09; not a replacement for specular VQ-03. | +| Cross-cutting | [PRD-341](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/done/PRD-341-a-frames-tone-is-a-number-and-the-number-is-a-gate.md) | Tone and luminance assertions | Implemented and archived by [PR #392](https://github.com/ThreeNativeHQ/threenative/pull/392), merged 2026-10-02. Reuse its captured-tone observations, assertions and CLI; a luminance score is not an aesthetic verdict. | Useful for 339, VQ-02 and matched material tests. | +| Cross-cutting | [PRD-342](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/AAA-visuals/PRD-342-where-the-frame-goes-pass-cost-ablation.md) | Measured post-stage ablation | Reuse rather than build another profiler. Inspect current frame/pass instrumentation first. | Useful for 455 and every optional expensive effect. | + +## Canonical checkout paths + +```text +docs/PRDs/lighting/PRD-269-motion-vectors-or-the-temporal-filters-lie.md +docs/PRDs/unreal-like-features/PRD-455-temporal-reconstruction-from-dynamic-resolution.md +docs/PRDs/AAA-visuals/PRD-339-the-frame-sets-its-own-exposure.md +docs/PRDs/unreal-like-features/PRD-460-invisible-streaming-transitions.md +docs/PRDs/unreal-like-features/PRD-456-distant-world-cell-proxies.md +docs/PRDs/unreal-like-features/PRD-457-virtual-shadows-scale-by-measurement.md +docs/PRDs/AAA-visuals/PRD-344-contact-occlusion-baked-from-the-geometry-it-ships-with.md +docs/PRDs/lighting/PRD-268-light-that-comes-from-off-screen.md +docs/PRDs/done/PRD-341-a-frames-tone-is-a-number-and-the-number-is-a-gate.md +docs/PRDs/AAA-visuals/PRD-342-where-the-frame-goes-pass-cost-ablation.md +``` + +## Companion work: resume, do not re-file + +- [PRD-454](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/unreal-like-features/PRD-454-worldcells-budget-real-resources.md): actual resource budgets; precondition to texture-residency extensions. +- [PRD-458](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/unreal-like-features/PRD-458-open-worlds-hold-60-fps-by-default.md) and [open-world PRD-473](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/unreal-like-features/PRD-473-open-worlds-hold-120-fps-gpu-driven.md): preserve merged GPU/LOD/shadow work and finish remaining visible/performance qualification, including impostor coverage/shadows. Their merged [PR #375](https://github.com/ThreeNativeHQ/threenative/pull/375) still describes open acceptance work. A merge does not establish 60/120 fps. +- [PRD-381](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/feature-mining/PRD-381-nine-mineable-seams-in-eanpa-sky.md): VQ-03 is the bounded local-reflection child for row 5; VQ-08 covers the cloud/overhead-field outcome related to row 4. Record these child links when executing that parent's own admission work; filing a child does not mean its gate passed. Local-shadow row 8 remains coordinated through PRD-457. +- [PRD-343](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/AAA-visuals/PRD-343-a-light-smaller-than-a-pixel-is-still-a-light.md) and [PRD-345](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/AAA-visuals/PRD-345-a-backlit-subject-is-not-a-hole-in-the-sky.md): optional existing work for subpixel emitters and authored backlit readability. Do not implement a compulsory rim light in core. +- [Merged rain/snow PR #382](https://github.com/ThreeNativeHQ/threenative/pull/382): reuse the kits and preserved completed PRDs. Only the reported native bloom regression is added here as VQ-02. Snow rolling resistance is nonvisual physics follow-up and is not silently included in this visual batch. + +The repository already has two different PRDs numbered 473. Use **full paths and titles**, not the number alone. New `VQ-01` through `VQ-15` identifiers intentionally avoid allocating more conflicting global integers. diff --git a/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-01-native-asset-capabilities.md b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-01-native-asset-capabilities.md new file mode 100644 index 0000000000..bd944151f2 --- /dev/null +++ b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-01-native-asset-capabilities.md @@ -0,0 +1,64 @@ +--- +prd_contract: v1 +--- + +# PRD-VQ-01 — Native asset compatibility follows the selected runtime and actual decoders + +**Status:** PROPOSED — 2026-10-01. No implementation or qualification is claimed. +**Batch:** [Visual quality execution batch](README.md). **Wave:** 0 / correctness. +**Dependencies:** None. This is a build/runtime contract repair, not permission to remove compatibility guards. + +## Grounding and intended outcome + +[packages/create-threenative/src/build.ts](https://github.com/ThreeNativeHQ/threenative/blob/d72778382b134ef8763f58825cb4d4fd8cc0f6e3/packages/create-threenative/src/build.ts) still rejects compressed assets by mobile target in `assertNativeAssetsCompatible`, while the runtime documentation identifies Android V8 as the default. The source establishes inconsistent capability selection; it does not prove that shipping V8 alone makes the Basis, Meshopt or Draco loading paths work. Workers, bundling, file access, decoder payloads and GPU formats are separate requirements. + +**Outcome:** A packaged game either decodes its declared assets on its selected runtime or is refused before publication with an accurate codec-specific reason. Android V8 and QuickJS must not be conflated; desktop QuickJS must not bypass checks simply because it is desktop. + +## Design and ownership + +Resolve one runtime capability record from the exact selected artifact/cohort before cooking. Thread it through asset cooking, the compatibility guard, native bundling and the runtime loader. Record engine, WASM support, packaged decoder versions and supported texture formats independently. An unknown capability takes an explicit decoder-free path or fails; it is never inferred from the build machine or from a desktop executable used to package Android. Keep QuickJS rollback supported. Do not silently change an authored asset or trust a manifest that disagrees with the packaged bytes. + +Reuse `runtimeHasWebAssembly`, `assertNativeAssetsCompatible`, asset compiler decoder options and `packages/runtime-native/scripts/bundle.mjs`. Extend the artifact capability contract only where necessary. No new renderer, codec implementation, or blanket Android whitelist. Preserve current WebGL and decoder-free fallbacks. + +## Required behavior + +- A table-driven suite covers web, desktop V8, desktop QuickJS, Android V8, Android QuickJS and unknown artifacts, with each codec independently allowed or refused. +- The loader validates actual KTX2 block formats and fallback transcodes. Mesh compression is separately tested; smaller download bytes are not reported as smaller GPU vertex buffers. +- Cook-cache keys include decoder capabilities and cohort identity. Switching engine or codec cannot reuse incompatible output. +- Diagnostics identify the asset, codec, selected artifact and missing capability. Build failure must leave the previous packaged artifact intact. + +## Execution phases + +All proof paths below are **planned implementation targets**, not existing passing tests. Reuse an existing equivalent test or scenario after inspecting current code, and update the canonical proof path rather than adding a duplicate. Follow [EXECUTE.md](EXECUTE.md) for fixture setup, variables, review and repository gates. + +### Phase 1 — One capability decision + +- [ ] Implement capability resolution from the selected artifact, including unknown-artifact handling and the full target/engine table. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-native-asset-capabilities.spec.ts`. +- [ ] Wire the same capability record into cooking and compatibility validation; preserve decoder-free rollback. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-native-asset-capabilities.spec.ts`. + +### Phase 2 — The packaged bytes are authoritative + +- [ ] Make bundling and loading retain exactly the declared decoders and invalidate stale cook-cache entries. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-native-asset-capabilities.spec.ts`. +- [ ] Create separate tiny textured/animated fixtures for KTX2, Meshopt and Draco; assert decoded texture content and geometry rather than only a successful import. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-native-asset-capabilities.spec.ts`. + +### Phase 3 — Qualify the visible result + +- [ ] The unchanged web fixture renders each codec correctly, with named adapter and no loader/GPU diagnostics. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-native-asset-capabilities.playtest.json --url ${VQ_URL:?} --browser-recipe webgpu`. +- [ ] The packaged Android V8 fixture decodes the admitted codecs on an emulator; unsupported codecs remain explicitly refused and the QuickJS decoder-free fixture still runs. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-native-asset-capabilities.playtest.json --target android --device ${VQ_ANDROID_DEVICE:?}`. + +## Acceptance criteria + +- [ ] All admitted codecs are demonstrated through the packaged loader, not merely through WASM availability; all refused combinations retain actionable build errors. proof: the completed Phase 3 scenario outputs, with the named fixture, package/cohort and adapter recorded inline here. +- [ ] The feature preserves its documented inactive/fallback path and releases owned resources after repeated lifecycle transitions. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-native-asset-capabilities.spec.ts` plus the Phase 3 lifecycle scenario. + +## Performance and promotion + +Record encoded bytes, decoded texture/geometry bytes and peak load memory per codec. Enabling a path requires correct pixels and bounded lifetime, not a promised compression ratio. Numerical targets are proposed acceptance targets, not benchmark results. Pin the fixture, metrics and thresholds before changing the implementation; never relax a failing threshold just to mark this PRD complete. Shared abstractions must pass the repository's reuse/LOC admission rule. Appearance remains editable source. + +## Blocked on + +Physical Android performance and thermals require a named phone and are separate from emulator correctness. Missing codec qualifications must remain individual exclusions. + +## Completion record + +Update the phase boxes and this PRD only after the named proof runs. Record actual results inline, including any remaining exclusions. A merged planning or implementation PR alone is not proof that every acceptance criterion passed. Archive according to the parent PRD filing rules when the work is genuinely complete. diff --git a/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-02-native-postprocessing-parity.md b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-02-native-postprocessing-parity.md new file mode 100644 index 0000000000..4e8b3a9cad --- /dev/null +++ b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-02-native-postprocessing-parity.md @@ -0,0 +1,64 @@ +--- +prd_contract: v1 +--- + +# PRD-VQ-02 — A requested post-processing stage never turns the native world into a blank frame + +**Status:** PROPOSED — 2026-10-01. No implementation or qualification is claimed. +**Batch:** [Visual quality execution batch](README.md). **Wave:** 0 / correctness. +**Dependencies:** None. Can start alongside VQ-01. + +## Grounding and intended outcome + +The merged [PR #382](https://github.com/ThreeNativeHQ/threenative/pull/382) reports that bloom at threshold 0.92 blanked the native snow world while web worked; the kit shipped bloom disabled. This is a reported regression, not a reproduced root cause. [packages/core/src/render/chain.ts](https://github.com/ThreeNativeHQ/threenative/blob/d72778382b134ef8763f58825cb4d4fd8cc0f6e3/packages/core/src/render/chain.ts) reports graph installation, which alone cannot prove visible output. + +**Outcome:** A minimal emissive fixture and the snow kit render correctly with bloom enabled on browser and native, or the stage is explicitly rejected before a blank frame is presented. The repair belongs to the identified failing layer, not to a hidden game-only workaround. + +## Design and ownership + +First reduce the reported snow case using its exact exposure, threshold, attachments and renderer cohort. Trace graph output, tone mapping, MRT allocation and native texture lifetime without assuming which is faulty. Keep one tone-map/output transform. A stage being constructed is not a visual success criterion. Preserve the no-post path, lazy attachment allocation and existing stage-disposal contract. + +Inspect the snow generated render source, shared `worldEnvironment.ts`, `RenderChain`, renderer output installation and native WebGPU replay only as the reproduction directs. No unrelated post-stack rewrite and no arbitrary brightness changes disguised as a bug fix. + +## Required behavior + +- Run bloom off/on, thresholds below/at/above 0.92, resize, scene switch and quality-tier transitions on the same fixture. +- Assert finite pixels, a nonblank world region and a measurable halo around the emissive test patch; inspect the world separately from the HUD. +- An unsupported stage reports its reason and preserves a valid world output; it must not be reported as visually qualified. +- Keep enabled and disabled resource lifetimes bounded across at least 20 toggles. + +## Execution phases + +All proof paths below are **planned implementation targets**, not existing passing tests. Reuse an existing equivalent test or scenario after inspecting current code, and update the canonical proof path rather than adding a duplicate. Follow [EXECUTE.md](EXECUTE.md) for fixture setup, variables, review and repository gates. + +### Phase 1 — Reproduce and repair the failing layer + +- [ ] Add the regression fixture and an assertion that detects the reported blank world independently of the HUD. proof: `pnpm exec vitest run packages/core/__tests__/vq-native-postprocessing-parity.spec.ts`. +- [ ] Fix the demonstrated source of failure while preserving exposure, tone mapping and the authored snow appearance. proof: `pnpm exec vitest run packages/core/__tests__/vq-native-postprocessing-parity.spec.ts`. + +### Phase 2 — Keep graph replacement safe + +- [ ] Cover resize, stage replacement and tier transitions without stale targets or duplicate output transforms. proof: `pnpm exec vitest run packages/core/__tests__/vq-native-postprocessing-parity.spec.ts`. +- [ ] Add effect-region assertions and allocation-lifetime checks, then restore bloom only on qualified paths. proof: `pnpm exec vitest run packages/core/__tests__/vq-native-postprocessing-parity.spec.ts`. + +### Phase 3 — Qualify the visible result + +- [ ] The emissive fixture and snow scene pass the off/on and threshold matrix on browser WebGPU. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-native-postprocessing-parity.playtest.json --url ${VQ_URL:?} --browser-recipe webgpu`. +- [ ] The same fixture and authored snow settings pass on a packaged Linux native host, with real world captures and zero GPU validation errors. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-native-postprocessing-parity.playtest.json --target desktop --executable ${VQ_NATIVE_EXECUTABLE:?}`. + +## Acceptance criteria + +- [ ] The original reported case is either reproduced and fixed or explicitly reclassified with the exact non-reproducing cohort; no unrelated change is presented as its fix. proof: the completed Phase 3 scenario outputs, with the named fixture, package/cohort and adapter recorded inline here. +- [ ] The feature preserves its documented inactive/fallback path and releases owned resources after repeated lifecycle transitions. proof: `pnpm exec vitest run packages/core/__tests__/vq-native-postprocessing-parity.spec.ts` plus the Phase 3 lifecycle scenario. + +## Performance and promotion + +Record bloom cost separately from world rendering. No unbounded render-target growth across 20 toggles and resizes. Numerical targets are proposed acceptance targets, not benchmark results. Pin the fixture, metrics and thresholds before changing the implementation; never relax a failing threshold just to mark this PRD complete. Shared abstractions must pass the repository's reuse/LOC admission rule. Appearance remains editable source. + +## Blocked on + +Other native operating systems and physical Android require their own runs before extending the qualification claim. + +## Completion record + +Update the phase boxes and this PRD only after the named proof runs. Record actual results inline, including any remaining exclusions. A merged planning or implementation PR alone is not proof that every acceptance criterion passed. Archive according to the parent PRD filing rules when the work is genuinely complete. diff --git a/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-03-local-reflection-probes.md b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-03-local-reflection-probes.md new file mode 100644 index 0000000000..a394698848 --- /dev/null +++ b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-03-local-reflection-probes.md @@ -0,0 +1,64 @@ +--- +prd_contract: v1 +--- + +# PRD-VQ-03 — Off-screen specular reflections come from a complete local probe + +**Status:** PROPOSED — 2026-10-01. No implementation or qualification is claimed. +**Batch:** [Visual quality execution batch](README.md). **Wave:** 1 / lighting. +**Dependencies:** Coordinate with PRD-381 row 5; this is its bounded child specification. Do not duplicate its capture-completeness work elsewhere. + +## Grounding and intended outcome + +[packages/core/src/render/probe-volume.ts](https://github.com/ThreeNativeHQ/threenative/blob/d72778382b134ef8763f58825cb4d4fd8cc0f6e3/packages/core/src/render/probe-volume.ts) owns diffuse irradiance, not local specular reflection. The existing [PRD-381](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/feature-mining/PRD-381-nine-mineable-seams-in-eanpa-sky.md) already identifies a dynamic local reflection probe. SSR and a global environment remain useful incumbents. + +**Outcome:** A polished object in a room reflects an off-camera landmark from that room. Entering a second room changes the fallback smoothly, without a half-updated cubemap, self-capture recursion or global-environment replacement for unrelated objects. + +## Design and ownership + +Reuse Three cube capture and PMREM. Maintain separate capture, completed and published generations; a six-face capture is published only after prefilter completion. A scene/light revision change invalidates an inconsistent generation. Bound capture work and coalesce refresh requests. Exclude the reflective receiver and viewmodel explicitly. Supply box-projection data and completed textures as mechanism; the generated material owns roughness, intensity and the SSR-to-probe-to-global composition. SSR confidence must not double-add specular energy. + +One box probe first, then deterministic blending of two overlapping probes. New shared code is limited to capture scheduling, versioning and ownership and must beat the two-consumer direct baseline. Shader sampling and all look choices stay in generated `src/render/`. + +## Required behavior + +- A failed or cancelled capture retains the last complete result; disposal releases owned targets without disposing borrowed scene assets. +- The two-room test uses a contrasting off-screen landmark and verifies a changed reflection without changing the visible room lighting. +- Box projection handles translation and declared scale; unsupported transforms fail explicitly. +- Material assignment is receiver-specific, and no enabled probe adds a second uncontrolled game loop. + +## Execution phases + +All proof paths below are **planned implementation targets**, not existing passing tests. Reuse an existing equivalent test or scenario after inspecting current code, and update the canonical proof path rather than adding a duplicate. Follow [EXECUTE.md](EXECUTE.md) for fixture setup, variables, review and repository gates. + +### Phase 1 — Complete captures and bounded ownership + +- [ ] Implement generation-safe incremental cube capture and PMREM publication using the existing render lifecycle. proof: `pnpm exec vitest run packages/core/__tests__/vq-local-reflection-probes.spec.ts`. +- [ ] Implement cancellation, coalesced invalidation and bounded two-probe resource ownership. proof: `pnpm exec vitest run packages/core/__tests__/vq-local-reflection-probes.spec.ts`. + +### Phase 2 — Compose the local specular fallback + +- [ ] Add game-owned box-projected sampling and deterministic overlap blending. proof: `pnpm exec vitest run packages/core/__tests__/vq-local-reflection-probes.spec.ts`. +- [ ] Integrate the existing SSR fallback without double-counting specular light and without capturing the viewmodel or receiver recursively. proof: `pnpm exec vitest run packages/core/__tests__/vq-local-reflection-probes.spec.ts`. + +### Phase 3 — Qualify the visible result + +- [ ] The two-room off-screen-landmark scenario verifies local reflection, overlap continuity and refresh behavior on WebGPU. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-local-reflection-probes.playtest.json --url ${VQ_URL:?} --browser-recipe webgpu`. +- [ ] The same package executes the two-room scenario on Linux native with complete-generation markers and matching probe selection. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-local-reflection-probes.playtest.json --target desktop --executable ${VQ_NATIVE_EXECUTABLE:?}`. + +## Acceptance criteria + +- [ ] The off-screen reflected landmark survives a camera turn that removes it from screen space; every visible probe generation is complete. proof: the completed Phase 3 scenario outputs, with the named fixture, package/cohort and adapter recorded inline here. +- [ ] The feature preserves its documented inactive/fallback path and releases owned resources after repeated lifecycle transitions. proof: `pnpm exec vitest run packages/core/__tests__/vq-local-reflection-probes.spec.ts` plus the Phase 3 lifecycle scenario. + +## Performance and promotion + +Report capture faces, prefilter cost, capture age and resident bytes. Bound active probes and skip redundant captures; no claim that dynamic probes are free. Numerical targets are proposed acceptance targets, not benchmark results. Pin the fixture, metrics and thresholds before changing the implementation; never relax a failing threshold just to mark this PRD complete. Shared abstractions must pass the repository's reuse/LOC admission rule. Appearance remains editable source. + +## Blocked on + +Physical-device quality/performance tiers are qualified separately; native support must not be extrapolated from a browser cube render. + +## Completion record + +Update the phase boxes and this PRD only after the named proof runs. Record actual results inline, including any remaining exclusions. A merged planning or implementation PR alone is not proof that every acceptance criterion passed. Archive according to the parent PRD filing rules when the work is genuinely complete. diff --git a/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-04-locomotion-blend-spaces.md b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-04-locomotion-blend-spaces.md new file mode 100644 index 0000000000..74d5cca547 --- /dev/null +++ b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-04-locomotion-blend-spaces.md @@ -0,0 +1,64 @@ +--- +prd_contract: v1 +--- + +# PRD-VQ-04 — Locomotion blends by speed and direction without restarting its gait + +**Status:** PROPOSED — 2026-10-01. No implementation or qualification is claimed. +**Batch:** [Visual quality execution batch](README.md). **Wave:** 1 / character motion. +**Dependencies:** Uses existing AnimationPlayer, SkeletalMesh3D and stride synchronization. Coordinate its action ownership with VQ-05. + +## Grounding and intended outcome + +[packages/core/src/animation.ts](https://github.com/ThreeNativeHQ/threenative/blob/d72778382b134ef8763f58825cb4d4fd8cc0f6e3/packages/core/src/animation.ts) already implements clip playback and crossfades. This PRD does not rebuild those. The remaining product outcome is continuously weighted, phase-coherent locomotion across speed and direction. Historical animation-state-machine restrictions remain in force: this is not a graph editor or serialized animation IR. + +**Outcome:** A licensed rig moves smoothly from idle through walking to running and strafes in a 2D direction space. Changing direction or speed does not repeatedly restart clips or introduce a one-frame pose pop. + +## Design and ownership + +Use ordinary Three AnimationActions with one authoritative updater. Put locomotion states, clip selection, thresholds and transitions in editable game TypeScript. Admit shared numerical weight/phase helpers only after two consumers demonstrate less total code. Use sorted intervals for 1D and a deterministic declared interpolation domain for 2D; handle points outside that domain explicitly. Preserve normalized phase for compatible gait clips, with an explicit opt-out for incompatible authored cycles. Do not confuse stride rate with root-motion extraction. + +Idle/walk/run and four-direction locomotion only. No motion matching, full Animator graph, visual editor, new asset format or automatic semantic inference from clip filenames. + +## Required behavior + +- Weights remain finite and nonnegative and sum to 1 within 1e-6; duplicate samples and degenerate 2D domains fail or use an explicitly documented fallback. +- Identical input replay is deterministic, and no independent mixer loop is created. +- A speed sweep preserves gait phase across compatible clips; a large instantaneous intent change has a bounded authored transition. +- Test rapid idle/walk/run/idle reversal and returning to a still-contributing action, not just a fresh third clip. + +## Execution phases + +All proof paths below are **planned implementation targets**, not existing passing tests. Reuse an existing equivalent test or scenario after inspecting current code, and update the canonical proof path rather than adding a duplicate. Follow [EXECUTE.md](EXECUTE.md) for fixture setup, variables, review and repository gates. + +### Phase 1 — Continuous weights with explicit boundaries + +- [ ] Implement and test deterministic 1D and 2D weight evaluation, including degenerate and out-of-domain inputs. proof: `pnpm exec vitest run packages/core/__tests__/vq-locomotion-blend-spaces.spec.ts`. +- [ ] Integrate weighted action ownership and phase synchronization without breaking existing play/once/stride behavior. proof: `pnpm exec vitest run packages/core/__tests__/vq-locomotion-blend-spaces.spec.ts`. + +### Phase 2 — Two real locomotion consumers + +- [ ] Drive a first-person-visible body and a third-person rig through the same weight/phase mechanism with game-owned settings. proof: `pnpm exec vitest run packages/core/__tests__/vq-locomotion-blend-spaces.spec.ts`. +- [ ] Expose selected clips, weights and phase in existing gameplay observations and verify rapid reversals against sampled poses. proof: `pnpm exec vitest run packages/core/__tests__/vq-locomotion-blend-spaces.spec.ts`. + +### Phase 3 — Qualify the visible result + +- [ ] The real-rig speed/strafe sweep passes weight, phase and pose-continuity assertions on browser WebGPU. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-locomotion-blend-spaces.playtest.json --url ${VQ_URL:?} --browser-recipe webgpu`. +- [ ] The identical input trace passes on Linux native; inspect the transition sequence rather than a single still frame. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-locomotion-blend-spaces.playtest.json --target desktop --executable ${VQ_NATIVE_EXECUTABLE:?}`. + +## Acceptance criteria + +- [ ] Continuous speed/direction changes require no game-specific replacement mixer, and a same-rig trace produces matching clip weights across the two qualified runtimes. proof: the completed Phase 3 scenario outputs, with the named fixture, package/cohort and adapter recorded inline here. +- [ ] The feature preserves its documented inactive/fallback path and releases owned resources after repeated lifecycle transitions. proof: `pnpm exec vitest run packages/core/__tests__/vq-locomotion-blend-spaces.spec.ts` plus the Phase 3 lifecycle scenario. + +## Performance and promotion + +Count active actions and allocations. Keep nonparticipants at the existing AnimationPlayer cost and document any extra per-rig work. Numerical targets are proposed acceptance targets, not benchmark results. Pin the fixture, metrics and thresholds before changing the implementation; never relax a failing threshold just to mark this PRD complete. Shared abstractions must pass the repository's reuse/LOC admission rule. Appearance remains editable source. + +## Blocked on + +A license-clear multi-clip rig is required. Use repository-owned fixtures where possible; downloading commercial animations is not assumed. + +## Completion record + +Update the phase boxes and this PRD only after the named proof runs. Record actual results inline, including any remaining exclusions. A merged planning or implementation PR alone is not proof that every acceptance criterion passed. Archive according to the parent PRD filing rules when the work is genuinely complete. diff --git a/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-05-masked-additive-animation.md b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-05-masked-additive-animation.md new file mode 100644 index 0000000000..7f1cbf3732 --- /dev/null +++ b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-05-masked-additive-animation.md @@ -0,0 +1,64 @@ +--- +prd_contract: v1 +--- + +# PRD-VQ-05 — Upper-body actions and additive reactions compose over locomotion + +**Status:** PROPOSED — 2026-10-01. No implementation or qualification is claimed. +**Batch:** [Visual quality execution batch](README.md). **Wave:** 1 / character motion. +**Dependencies:** Coordinate with VQ-04 through one action owner. Existing constrained IK must remain after authored animation evaluation. + +## Grounding and intended outcome + +[packages/core/src/animation.ts](https://github.com/ThreeNativeHQ/threenative/blob/d72778382b134ef8763f58825cb4d4fd8cc0f6e3/packages/core/src/animation.ts) exposes the Three mixer and existing clip transitions. Additive animation is an upstream Three capability, not missing mathematics. What needs qualification is masked layer composition, reference-pose handling, lifecycle and ordering for actual ThreeNative characters. + +**Outcome:** A character continues walking while aiming or reloading; recoil and breathing add to the pose without replacing the lower-body gait. Removing a layer restores the underlying animation with no accumulated drift. + +## Design and ownership + +Keep state selection and masks in game-owned TypeScript. Resolve masks against cloned rigs, filter or weight tracks through a single mixer owner, and reuse upstream additive-clip preparation against an explicit reference pose. Never modify shared source clips. Distinguish override layers from additive deltas and define quaternion normalization. Order: locomotion/base, override/additive layers, IK, render; root movement retains its existing owner. A generalized animation graph is explicitly out of scope. + +One base layer, one masked override and two bounded additive layers; masks are explicit bone names with optional descendant expansion. Face-control and root-motion ownership conflicts must be refused or explicitly excluded, not silently mixed. + +## Required behavior + +- With layer weight zero, sampled bone transforms equal the base-only result within numeric tolerance. +- Two cloned characters sharing source clips can use different masks and weights without cross-talk. +- Missing bones, incompatible tracks and missing additive reference poses are actionable errors. +- Loop/once completion, interrupted reloads, repeated weight ramps and removal/disposal leave no residual pose or live action. + +## Execution phases + +All proof paths below are **planned implementation targets**, not existing passing tests. Reuse an existing equivalent test or scenario after inspecting current code, and update the canonical proof path rather than adding a duplicate. Follow [EXECUTE.md](EXECUTE.md) for fixture setup, variables, review and repository gates. + +### Phase 1 — Correct layer data and ownership + +- [ ] Implement mask resolution and immutable additive preparation using ordinary Three clips/actions. proof: `pnpm exec vitest run packages/core/__tests__/vq-masked-additive-animation.spec.ts`. +- [ ] Add deterministic composition and reference-pose tests, including independent cloned characters. proof: `pnpm exec vitest run packages/core/__tests__/vq-masked-additive-animation.spec.ts`. + +### Phase 2 — Integrate locomotion and IK ordering + +- [ ] Compose reload/aim and recoil over the VQ-04 or existing locomotion consumer with one updater. proof: `pnpm exec vitest run packages/core/__tests__/vq-masked-additive-animation.spec.ts`. +- [ ] Verify root ownership, IK-after-animation ordering, cancellation and layer removal through pose observations. proof: `pnpm exec vitest run packages/core/__tests__/vq-masked-additive-animation.spec.ts`. + +### Phase 3 — Qualify the visible result + +- [ ] A walking/reloading/recoiling character passes lower-body preservation and layer-removal assertions on WebGPU. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-masked-additive-animation.playtest.json --url ${VQ_URL:?} --browser-recipe webgpu`. +- [ ] The identical layered trace passes on Linux native with sampled bone transforms and retained source-clip hashes. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-masked-additive-animation.playtest.json --target desktop --executable ${VQ_NATIVE_EXECUTABLE:?}`. + +## Acceptance criteria + +- [ ] Layer weight zero is a base-only identity, and removing all added layers restores base animation without pose drift or shared-rig mutation. proof: the completed Phase 3 scenario outputs, with the named fixture, package/cohort and adapter recorded inline here. +- [ ] The feature preserves its documented inactive/fallback path and releases owned resources after repeated lifecycle transitions. proof: `pnpm exec vitest run packages/core/__tests__/vq-masked-additive-animation.spec.ts` plus the Phase 3 lifecycle scenario. + +## Performance and promotion + +Bound layer and action counts. Measure CPU per rig; no mandatory overhead for characters using only the existing player. Numerical targets are proposed acceptance targets, not benchmark results. Pin the fixture, metrics and thresholds before changing the implementation; never relax a failing threshold just to mark this PRD complete. Shared abstractions must pass the repository's reuse/LOC admission rule. Appearance remains editable source. + +## Blocked on + +Physical-device crowd scaling and additional character rigs need separate qualification; these do not block the two-runtime correctness slice. + +## Completion record + +Update the phase boxes and this PRD only after the named proof runs. Record actual results inline, including any remaining exclusions. A merged planning or implementation PR alone is not proof that every acceptance criterion passed. Archive according to the parent PRD filing rules when the work is genuinely complete. diff --git a/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-06-many-local-lights.md b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-06-many-local-lights.md new file mode 100644 index 0000000000..6627765051 --- /dev/null +++ b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-06-many-local-lights.md @@ -0,0 +1,64 @@ +--- +prd_contract: v1 +--- + +# PRD-VQ-06 — Many local lights use a qualified upstream tiled or clustered path + +**Status:** PROPOSED — 2026-10-01. No implementation or qualification is claimed. +**Batch:** [Visual quality execution batch](README.md). **Wave:** 2 / scalable lighting. +**Dependencies:** Use PRD-457 for local shadow work. This PRD owns direct-light selection, not a new shadow atlas. + +## Grounding and intended outcome + +The reviewed render surface does not expose a qualified many-light route. Current upstream documents [TiledLightsNode](https://threejs.org/docs/pages/TiledLightsNode.html), [ClusteredLightsNode](https://threejs.org/docs/pages/ClusteredLightsNode.html) and [DynamicLightsNode](https://threejs.org/docs/pages/DynamicLightsNode.html). [pnpm-workspace.yaml](https://github.com/ThreeNativeHQ/threenative/blob/d72778382b134ef8763f58825cb4d4fd8cc0f6e3/pnpm-workspace.yaml) pins Three 0.185.1: online availability is not proof that an addon exists or works in this pin. + +**Outcome:** A corridor/city-night fixture with 256 unshadowed point lights renders the same intended lighting at a lower measured cost than the ordinary per-light baseline on a workload where light-list culling helps. + +## Design and ownership + +Inspect the installed Three pin and patches before selecting a donor. Prefer its supported tiled/clustered or dynamic-light implementation. Use an upstream-compatible upgrade only with regression qualification; do not write a parallel Forward+ renderer from the audit wording. Unsupported light types, cookies and shadowed lights retain an explicit stock route. Cluster overflow must preserve illumination through a correct fallback rather than dropping lights. Game source owns light intensities, colors and geometry. + +Point-light throughput first; explicitly enumerate support for spots, directional lights, transparency and shadow-casting lights. Keep the existing renderer, material system and directional shadow path. + +## Required behavior + +- A correctness fixture compares the optimized and reference direct-light results before temporal or post effects. +- Overflow, camera clipping, light movement, addition/removal and depth-separated lights are covered. +- A missing addon or unsupported native feature is reported, not replaced with an unqualified backend. +- The existing PBR, animated/instanced and probe-consuming material fixtures keep their intended lighting. + +## Execution phases + +All proof paths below are **planned implementation targets**, not existing passing tests. Reuse an existing equivalent test or scenario after inspecting current code, and update the canonical proof path rather than adding a duplicate. Follow [EXECUTE.md](EXECUTE.md) for fixture setup, variables, review and repository gates. + +### Phase 1 — Admit the installed upstream path + +- [ ] Integrate the smallest compatible upstream lighting route with explicit per-light support and a correct fallback. proof: `pnpm exec vitest run packages/core/__tests__/vq-many-local-lights.spec.ts`. +- [ ] Cover light-list correctness, overflow and scene-lifetime changes against the ordinary Three path. proof: `pnpm exec vitest run packages/core/__tests__/vq-many-local-lights.spec.ts`. + +### Phase 2 — Connect real materials and measured selection + +- [ ] Exercise the route on animated, instanced and transparent receiver fixtures without replacing their material ownership. proof: `pnpm exec vitest run packages/core/__tests__/vq-many-local-lights.spec.ts`. +- [ ] Add direct-light work counters and a measured opt-in/admission decision for the representative many-light workload. proof: `pnpm exec vitest run packages/core/__tests__/vq-many-local-lights.spec.ts`. + +### Phase 3 — Qualify the visible result + +- [ ] The 256-light scene passes image/correctness checks and a paired GPU-cost comparison on a named WebGPU adapter. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-many-local-lights.playtest.json --url ${VQ_URL:?} --browser-recipe webgpu`. +- [ ] The same fixture passes on Linux native and records its own cost result; a browser speedup is not reused as a native result. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-many-local-lights.playtest.json --target desktop --executable ${VQ_NATIVE_EXECUTABLE:?}`. + +## Acceptance criteria + +- [ ] The optimized route preserves the reference illumination and wins on the declared many-light workload; otherwise keep it opt-in or decline it with the measurement. proof: the completed Phase 3 scenario outputs, with the named fixture, package/cohort and adapter recorded inline here. +- [ ] The feature preserves its documented inactive/fallback path and releases owned resources after repeated lifecycle transitions. proof: `pnpm exec vitest run packages/core/__tests__/vq-many-local-lights.spec.ts` plus the Phase 3 lifecycle scenario. + +## Performance and promotion + +Measure direct-light and shadow cost separately. No claim that 256 shadowed lights or every spot-light feature is supported by a point-light cluster implementation. Numerical targets are proposed acceptance targets, not benchmark results. Pin the fixture, metrics and thresholds before changing the implementation; never relax a failing threshold just to mark this PRD complete. Shared abstractions must pass the repository's reuse/LOC admission rule. Appearance remains editable source. + +## Blocked on + +Additional hardware and Three upgrades require their own compatibility runs before default-on promotion. + +## Completion record + +Update the phase boxes and this PRD only after the named proof runs. Record actual results inline, including any remaining exclusions. A merged planning or implementation PR alone is not proof that every acceptance criterion passed. Archive according to the parent PRD filing rules when the work is genuinely complete. diff --git a/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-07-volumetric-fog.md b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-07-volumetric-fog.md new file mode 100644 index 0000000000..89257e20a3 --- /dev/null +++ b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-07-volumetric-fog.md @@ -0,0 +1,64 @@ +--- +prd_contract: v1 +--- + +# PRD-VQ-07 — Local volumetric fog composes with depth, lights and existing atmosphere + +**Status:** PROPOSED — 2026-10-01. No implementation or qualification is claimed. +**Batch:** [Visual quality execution batch](README.md). **Wave:** 2 / atmosphere. +**Dependencies:** Independent of clouds. Reuse VQ-06 only for any local-light feature it has actually qualified. + +## Grounding and intended outcome + +ThreeNative already has atmosphere LUTs and god-ray composition. Current upstream [VolumeNodeMaterial](https://threejs.org/docs/pages/VolumeNodeMaterial.html) and volumetric lighting machinery are reuse candidates, not proof of a finished ThreeNative fog product. Recheck the installed pin and the merged rain kit before introducing a new algorithm. + +**Outcome:** A bounded mist volume in an interior/exterior fixture responds to the main light and declared local lights, is occluded by solid geometry and blends into the existing atmosphere without becoming a uniformly bright screen overlay. + +## Design and ownership + +Start with the supported upstream volume/material or existing kit implementation. Density functions, phase function, color and artistic controls remain generated TSL/game source. Share only depth access, lifetime and ordered dispatch that the current render loop cannot already supply. Composite radiance with transmittance in the scene-linear graph before its one output transform; specify the relationship with aerial perspective and god rays so the same medium is not added twice. Keep history optional until its disocclusion behavior is qualified. + +A bounded volume and height-dependent density, one directional source and an explicitly supported local-light subset. No mandatory froxel engine, general weather manager, or promise that all point/spot shadow types work. + +## Required behavior + +- Zero density produces the no-fog image; an opaque foreground wall hides fog behind it. +- The fixture tests the camera both outside and inside the volume, a light toggle and overlapping density bounds. +- Step count and resolution are quality controls, with an explicit off/unsupported route and no dormant GPU allocations. +- Resizes, camera cuts and streamed occluder changes do not reuse invalid depth/history. + +## Execution phases + +All proof paths below are **planned implementation targets**, not existing passing tests. Reuse an existing equivalent test or scenario after inspecting current code, and update the canonical proof path rather than adding a duplicate. Follow [EXECUTE.md](EXECUTE.md) for fixture setup, variables, review and repository gates. + +### Phase 1 — Depth-correct participating volume + +- [ ] Implement game-owned volumetric composition using the admitted upstream/kit mechanism and shared scene depth. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-volumetric-fog.spec.ts`. +- [ ] Cover zero density, inside/outside camera positions and opaque occlusion with analytic or reference fixtures. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-volumetric-fog.spec.ts`. + +### Phase 2 — Compose with the existing environment + +- [ ] Integrate directional and the declared local-light subset without double-applying atmosphere or god rays. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-volumetric-fog.spec.ts`. +- [ ] Add bounded quality settings, history invalidation where used and deterministic resource disposal. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-volumetric-fog.spec.ts`. + +### Phase 3 — Qualify the visible result + +- [ ] The fog fixture verifies occlusion, light response and zero-density identity on browser WebGPU with fixed-camera captures. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-volumetric-fog.playtest.json --url ${VQ_URL:?} --browser-recipe webgpu`. +- [ ] The same authored volume runs on Linux native and remains valid through resize and scene teardown. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-volumetric-fog.playtest.json --target desktop --executable ${VQ_NATIVE_EXECUTABLE:?}`. + +## Acceptance criteria + +- [ ] Fog is depth-correct and light-responsive, and turning it off restores the original graph and allocation baseline. proof: the completed Phase 3 scenario outputs, with the named fixture, package/cohort and adapter recorded inline here. +- [ ] The feature preserves its documented inactive/fallback path and releases owned resources after repeated lifecycle transitions. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-volumetric-fog.spec.ts` plus the Phase 3 lifecycle scenario. + +## Performance and promotion + +Record pixels, ray steps, light count and cost on the same fixture. Choose tier admission from measurements, not an arbitrary AAA label. Numerical targets are proposed acceptance targets, not benchmark results. Pin the fixture, metrics and thresholds before changing the implementation; never relax a failing threshold just to mark this PRD complete. Shared abstractions must pass the repository's reuse/LOC admission rule. Appearance remains editable source. + +## Blocked on + +Phone performance and a wider local-shadow set are separate qualification work. + +## Completion record + +Update the phase boxes and this PRD only after the named proof runs. Record actual results inline, including any remaining exclusions. A merged planning or implementation PR alone is not proof that every acceptance criterion passed. Archive according to the parent PRD filing rules when the work is genuinely complete. diff --git a/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-08-clouds-and-overhead-transmittance.md b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-08-clouds-and-overhead-transmittance.md new file mode 100644 index 0000000000..39bb5aa638 --- /dev/null +++ b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-08-clouds-and-overhead-transmittance.md @@ -0,0 +1,64 @@ +--- +prd_contract: v1 +--- + +# PRD-VQ-08 — Clouds and their ground attenuation share one authored field + +**Status:** PROPOSED — 2026-10-01. No implementation or qualification is claimed. +**Batch:** [Visual quality execution batch](README.md). **Wave:** 2 / atmosphere. +**Dependencies:** Reuse the merged rain/snow kits and PRD-381 row 4. Coordinate atmosphere composition with VQ-07; do not recreate the kits. + +## Grounding and intended outcome + +[PR #382](https://github.com/ThreeNativeHQ/threenative/pull/382) is merged and owns rain/snow starter outcomes. [PRD-381](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/feature-mining/PRD-381-nine-mineable-seams-in-eanpa-sky.md) already identifies an overhead attenuation-field seam. The remaining target is coherent cloud rendering and moving cloud shade, not a claim that weather or atmosphere is absent. + +**Outcome:** An authored cloud layer moves above an outdoor scene and the associated ground attenuation follows the same field and wind. A sun/coverage change does not leave stale shadow tiles or replace the sky with a detached flat overlay. + +## Design and ownership + +Inventory the actual rain render source first; keep everything that already meets the outcome. Reuse the atmosphere data and upstream volume tools. The game owns the density field, noise assets, optical controls and motion. Only if duplication justifies it, add the PRD-381 numeric transmittance capture/lifetime seam: texel-snapped world coordinates, bounded coverage, complete generations and declared update age. The visible cloud and ground sampler share parameters, not separately tuned animations. + +One regional cloud layer and one directional attenuation field. No global weather simulation, lightning rewrite, astronomical ephemeris rewrite or universal multi-scattering solver. An optional 2D fallback must be named as such. + +## Required behavior + +- Zero coverage preserves the existing sky and unit ground transmittance; density is finite and transmittance stays in [0,1]. +- A deterministic wind trace moves a known cloud and its ground footprint consistently in world coordinates. +- Teleport, sun-direction changes and quality changes invalidate stale coverage without showing an incomplete generation. +- Occluded sky pixels and fog/atmosphere ordering remain correct; cloud attenuation does not erase local artificial lighting. + +## Execution phases + +All proof paths below are **planned implementation targets**, not existing passing tests. Reuse an existing equivalent test or scenario after inspecting current code, and update the canonical proof path rather than adding a duplicate. Follow [EXECUTE.md](EXECUTE.md) for fixture setup, variables, review and repository gates. + +### Phase 1 — One cloud field with reusable inputs + +- [ ] Reuse or extend kit cloud rendering so density, wind and lighting are driven by one declared game-owned parameter set. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-clouds-and-overhead-transmittance.spec.ts`. +- [ ] Produce bounded directional transmittance from that same field, admitting shared capture machinery only when it reduces duplicate code. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-clouds-and-overhead-transmittance.spec.ts`. + +### Phase 2 — Stable world-space composition + +- [ ] Integrate cloud radiance and direct-sun attenuation with the existing atmosphere and lighting graph. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-clouds-and-overhead-transmittance.spec.ts`. +- [ ] Implement complete-generation publication, coverage invalidation and quality/resource limits for moving viewpoints. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-clouds-and-overhead-transmittance.spec.ts`. + +### Phase 3 — Qualify the visible result + +- [ ] The cloud/ground-footprint trace passes on WebGPU, including zero coverage, sun rotation and teleport. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-clouds-and-overhead-transmittance.playtest.json --url ${VQ_URL:?} --browser-recipe webgpu`. +- [ ] The same trace and parameter set pass on Linux native; record the actual cloud path and attenuation generation. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-clouds-and-overhead-transmittance.playtest.json --target desktop --executable ${VQ_NATIVE_EXECUTABLE:?}`. + +## Acceptance criteria + +- [ ] Visible cloud motion and ground attenuation agree on the authored field, while no-cloud mode preserves the preexisting scene. proof: the completed Phase 3 scenario outputs, with the named fixture, package/cohort and adapter recorded inline here. +- [ ] The feature preserves its documented inactive/fallback path and releases owned resources after repeated lifecycle transitions. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-clouds-and-overhead-transmittance.spec.ts` plus the Phase 3 lifecycle scenario. + +## Performance and promotion + +Measure the visible volume and overhead-field capture separately. Do not enable a costly cloud tier by default without the paired frame budget. Numerical targets are proposed acceptance targets, not benchmark results. Pin the fixture, metrics and thresholds before changing the implementation; never relax a failing threshold just to mark this PRD complete. Shared abstractions must pass the repository's reuse/LOC admission rule. Appearance remains editable source. + +## Blocked on + +The optional shared overhead-field extraction is gated by PRD-381 reuse/admission rules; missing artistic noise assets need license-clear substitutes. + +## Completion record + +Update the phase boxes and this PRD only after the named proof runs. Record actual results inline, including any remaining exclusions. A merged planning or implementation PR alone is not proof that every acceptance criterion passed. Archive according to the parent PRD filing rules when the work is genuinely complete. diff --git a/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-09-incremental-diffuse-relighting.md b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-09-incremental-diffuse-relighting.md new file mode 100644 index 0000000000..82db4fe160 --- /dev/null +++ b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-09-incremental-diffuse-relighting.md @@ -0,0 +1,64 @@ +--- +prd_contract: v1 +--- + +# PRD-VQ-09 — Diffuse probes refresh bounded changed regions without a visible half-bake + +**Status:** PROPOSED — 2026-10-01. No implementation or qualification is claimed. +**Batch:** [Visual quality execution batch](README.md). **Wave:** 3 / gated GI extension. +**Dependencies:** First reconcile and qualify existing PRD-268. The incumbent ProbeVolume remains the single diffuse-probe owner. + +## Grounding and intended outcome + +[packages/core/src/render/probe-volume.ts](https://github.com/ThreeNativeHQ/threenative/blob/d72778382b134ef8763f58825cb4d4fd8cc0f6e3/packages/core/src/render/probe-volume.ts) already performs static diffuse capture and exposes rebaking. Existing [PRD-268](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/lighting/PRD-268-light-that-comes-from-off-screen.md) owns that path. This proposal is only for measured gaps in incremental relighting; manual rebaking must be evaluated before new code is admitted. + +**Outcome:** Changing an off-screen lamp or opening a door updates the affected diffuse lighting within a declared latency budget while unaffected regions retain a complete valid result. This is bounded probe relighting, not Lumen parity. + +## Design and ownership + +Use the existing ProbeVolume capture/sample infrastructure and explicit scene/light revision invalidation. Coalesce dirty regions and schedule work through the existing lifecycle. Publish completed coefficient generations atomically; no reader sees a half-updated atlas. Define previous-versus-current bounce inputs to avoid energy accumulation. Keep artistic response and application in generated materials. If the existing rebake path already satisfies the tests and budget, close this proposal as covered rather than adding a scheduler. + +A small indoor volume, one changed lamp and one door/occluder case. No hardware RT dependency, whole-world fully dynamic GI, infinite bounces, or replacement of SSGI. + +## Required behavior + +- The off-screen source test changes diffuse response even when the lamp remains outside the camera. +- A completed refresh converges toward a full rebake reference within the declared fixture tolerance. +- Unchanged regions do not continually rebake, requests coalesce and cancelled generations never publish. +- Total energy remains bounded over repeated lamp toggles and repeated bake cycles. + +## Execution phases + +All proof paths below are **planned implementation targets**, not existing passing tests. Reuse an existing equivalent test or scenario after inspecting current code, and update the canonical proof path rather than adding a duplicate. Follow [EXECUTE.md](EXECUTE.md) for fixture setup, variables, review and repository gates. + +### Phase 1 — Bounded dirty-region updates + +- [ ] Extend only the demonstrated gaps in existing rebaking with revision-aware dirty regions and bounded scheduling. proof: `pnpm exec vitest run packages/core/__tests__/vq-incremental-diffuse-relighting.spec.ts`. +- [ ] Implement atomic atlas/coefficients publication and cancellation without a second diffuse-probe cache. proof: `pnpm exec vitest run packages/core/__tests__/vq-incremental-diffuse-relighting.spec.ts`. + +### Phase 2 — Convergence and stable composition + +- [ ] Verify changed-lamp and door response against the full-rebake reference, including repeated bounce cycles. proof: `pnpm exec vitest run packages/core/__tests__/vq-incremental-diffuse-relighting.spec.ts`. +- [ ] Integrate the refreshed diffuse term with the existing material and SSGI composition without duplicate contribution. proof: `pnpm exec vitest run packages/core/__tests__/vq-incremental-diffuse-relighting.spec.ts`. + +### Phase 3 — Qualify the visible result + +- [ ] The lamp/door scenario records refresh latency, unchanged-region work and radiance convergence on WebGPU. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-incremental-diffuse-relighting.playtest.json --url ${VQ_URL:?} --browser-recipe webgpu`. +- [ ] The same scenario passes on Linux native with its own measured refresh budget and complete-generation observations. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-incremental-diffuse-relighting.playtest.json --target desktop --executable ${VQ_NATIVE_EXECUTABLE:?}`. + +## Acceptance criteria + +- [ ] The admitted incremental route performs less work than a full rebake for localized changes while meeting a predeclared image and latency bound; otherwise retain the incumbent. proof: the completed Phase 3 scenario outputs, with the named fixture, package/cohort and adapter recorded inline here. +- [ ] The feature preserves its documented inactive/fallback path and releases owned resources after repeated lifecycle transitions. proof: `pnpm exec vitest run packages/core/__tests__/vq-incremental-diffuse-relighting.spec.ts` plus the Phase 3 lifecycle scenario. + +## Performance and promotion + +Pin probe count, density, bounce count and changed region before comparison. A 500 ms response goal is an initial fixture target, not a claimed current engine capability. Numerical targets are proposed acceptance targets, not benchmark results. Pin the fixture, metrics and thresholds before changing the implementation; never relax a failing threshold just to mark this PRD complete. Shared abstractions must pass the repository's reuse/LOC admission rule. Appearance remains editable source. + +## Blocked on + +PRD-268 qualification and a representative dynamic-lighting consumer precede default admission; hardware-specific quality tiers remain separate. + +## Completion record + +Update the phase boxes and this PRD only after the named proof runs. Record actual results inline, including any remaining exclusions. A merged planning or implementation PR alone is not proof that every acceptance criterion passed. Archive according to the parent PRD filing rules when the work is genuinely complete. diff --git a/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-10-texture-mip-residency.md b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-10-texture-mip-residency.md new file mode 100644 index 0000000000..55c0f8415a --- /dev/null +++ b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-10-texture-mip-residency.md @@ -0,0 +1,64 @@ +--- +prd_contract: v1 +--- + +# PRD-VQ-10 — Texture residency releases real GPU memory rather than only biasing sampling + +**Status:** PROPOSED — 2026-10-01. No implementation or qualification is claimed. +**Batch:** [Visual quality execution batch](README.md). **Wave:** 3 / memory-gated. +**Dependencies:** Reconcile PRD-454 resource budgets and VQ-01 decoder selection first. + +## Grounding and intended outcome + +Existing asset cooking and world-cell residency already manage models, compressed textures and lifetimes. [PRD-454](https://github.com/ThreeNativeHQ/threenative/blob/develop/docs/PRDs/unreal-like-features/PRD-454-worldcells-budget-real-resources.md) owns truthful world-resource budgeting. This slice addresses a measured residual texture-memory bottleneck; it does not assume that lack of virtual texturing is itself a defect. + +**Outcome:** A detailed world uses high-detail textures near the player, evicts unnecessary high-detail representations under a hard byte budget and restores them without black materials, stale binds or unbounded cache growth. + +## Design and ownership + +Begin with separately loadable cooked resolution variants or an available portable mip-loading mechanism. Merely changing LOD bias or sampler LOD limits does not count as memory reclamation. The existing asset owner holds shared references; replace representations atomically and retire GPU resources only after in-flight use is safe. Prioritize current view demand with hysteresis and cancellation, preserve a valid low-detail fallback, and report both committed and pending GPU bytes. No sparse-texture assumption or full runtime virtual-texturing system in v1. + +Color/normal/roughness texture families in a representative streamed world; preserve color-space, normal-map and material binding semantics. No tile-feedback renderer or unrelated geometry streaming rewrite. + +## Required behavior + +- Shared textures are counted once, and active materials never reference disposed textures. +- A hard budget includes pending replacement overlap and a reserved fallback; over-budget pressure is reported rather than hidden. +- Teleport, cancellation and two out-and-back routes return resident resources to the expected baseline. +- Improvement is shown in real allocation/residency accounting, not only smaller files or a visually blurrier frame. + +## Execution phases + +All proof paths below are **planned implementation targets**, not existing passing tests. Reuse an existing equivalent test or scenario after inspecting current code, and update the canonical proof path rather than adding a duplicate. Follow [EXECUTE.md](EXECUTE.md) for fixture setup, variables, review and repository gates. + +### Phase 1 — Cooked variants and truthful ownership + +- [ ] Extend the existing cook/manifest only with the required variant records and capability-aware cache identity. proof: `pnpm exec vitest run packages/core/__tests__/vq-texture-mip-residency.spec.ts`. +- [ ] Implement shared variant lifetime and byte accounting including pending uploads and in-flight retirement. proof: `pnpm exec vitest run packages/core/__tests__/vq-texture-mip-residency.spec.ts`. + +### Phase 2 — Bounded demand and safe replacement + +- [ ] Add budgeted demand, hysteresis and cancellation while retaining a valid fallback representation. proof: `pnpm exec vitest run packages/core/__tests__/vq-texture-mip-residency.spec.ts`. +- [ ] Wire atomic material replacement and verify repeated streaming/teleport cycles release actual high-detail allocations. proof: `pnpm exec vitest run packages/core/__tests__/vq-texture-mip-residency.spec.ts`. + +### Phase 3 — Qualify the visible result + +- [ ] A fixed world route stays inside the declared allocation budget and demonstrates near-detail restoration on browser WebGPU. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-texture-mip-residency.playtest.json --url ${VQ_URL:?} --browser-recipe webgpu`. +- [ ] The same cooked package and budget contract pass on Linux native, with explicit decoder/format reporting. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-texture-mip-residency.playtest.json --target desktop --executable ${VQ_NATIVE_EXECUTABLE:?}`. + +## Acceptance criteria + +- [ ] The route reduces measured resident texture bytes while preserving near-field quality and avoiding missing-texture frames; no demonstrated bottleneck means defer the feature. proof: the completed Phase 3 scenario outputs, with the named fixture, package/cohort and adapter recorded inline here. +- [ ] The feature preserves its documented inactive/fallback path and releases owned resources after repeated lifecycle transitions. proof: `pnpm exec vitest run packages/core/__tests__/vq-texture-mip-residency.spec.ts` plus the Phase 3 lifecycle scenario. + +## Performance and promotion + +Use a fixed 256 MiB test budget only for the synthetic fixture, not as a shipping default. Include overlap and fallback bytes; measure upload hitches separately. Numerical targets are proposed acceptance targets, not benchmark results. Pin the fixture, metrics and thresholds before changing the implementation; never relax a failing threshold just to mark this PRD complete. Shared abstractions must pass the repository's reuse/LOC admission rule. Appearance remains editable source. + +## Blocked on + +A world with an observed texture-memory bottleneck is required for admission. Mobile claims require decoder qualification and a named device run. + +## Completion record + +Update the phase boxes and this PRD only after the named proof runs. Record actual results inline, including any remaining exclusions. A merged planning or implementation PR alone is not proof that every acceptance criterion passed. Archive according to the parent PRD filing rules when the work is genuinely complete. diff --git a/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-11-bounded-decals.md b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-11-bounded-decals.md new file mode 100644 index 0000000000..1cf6e4ea52 --- /dev/null +++ b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-11-bounded-decals.md @@ -0,0 +1,64 @@ +--- +prd_contract: v1 +--- + +# PRD-VQ-11 — Impact and environment decals use a bounded portable lifecycle + +**Status:** PROPOSED — 2026-10-01. No implementation or qualification is claimed. +**Batch:** [Visual quality execution batch](README.md). **Wave:** 2 / high-payoff detail. +**Dependencies:** Independent. Share receiver/base-geometry selection with existing LOD and picking paths. + +## Grounding and intended outcome + +Upstream [DecalGeometry](https://threejs.org/docs/pages/DecalGeometry.html) already provides mesh projection. The earlier audit must not be interpreted as permission to rewrite that algorithm. The useful product gap is qualified receiver handling, pooling, lifetime and game-owned material composition for real impacts. + +**Outcome:** Repeated bullet impacts and environment marks remain attached to their receivers, respect normals and occlusion, and stay within a fixed resource cap as the player moves or the scene unloads. + +## Design and ownership + +Start from ordinary Three decal geometry and generated materials. Reuse existing hit results, object transforms and authored LOD0 geometry rather than raycasting the whole world again. Admit a shared lifecycle owner only when at least two consumers need it. Keep material, atlas choice, color, depth bias and fade curves in generated source. A world-static mark and a rigid-moving receiver are separate supported cases; skinned or deforming decals are explicitly refused in v1. + +Surface-color impacts and environment marks on static/rigid opaque receivers. No deferred G-buffer decal renderer, normal/roughness channel rewrite, skinned tattoo system or virtual-texture painting. + +## Required behavior + +- A cap of 256 decals in the fixture is enforced with deterministic eviction, and receiver teardown removes its marks. +- A mark stays on a rigid receiver under translation/rotation; nonuniform or unsupported transforms have a specified behavior. +- Receiver isolation avoids marks projecting through nearby unrelated geometry; corner distortion is documented. +- LOD changes do not alter the gameplay hit surface or strand a decal on disposed geometry. + +## Execution phases + +All proof paths below are **planned implementation targets**, not existing passing tests. Reuse an existing equivalent test or scenario after inspecting current code, and update the canonical proof path rather than adding a duplicate. Follow [EXECUTE.md](EXECUTE.md) for fixture setup, variables, review and repository gates. + +### Phase 1 — Reuse projection and bound lifetime + +- [ ] Integrate upstream decal projection with existing picking/base-geometry data and explicit receiver support. proof: `pnpm exec vitest run packages/core/__tests__/vq-bounded-decals.spec.ts`. +- [ ] Implement deterministic pool limits, eviction, receiver cleanup and borrowed-resource ownership. proof: `pnpm exec vitest run packages/core/__tests__/vq-bounded-decals.spec.ts`. + +### Phase 2 — Preserve authored appearance and receiver motion + +- [ ] Add game-owned decal material/atlas composition with bounded bias and fade controls. proof: `pnpm exec vitest run packages/core/__tests__/vq-bounded-decals.spec.ts`. +- [ ] Verify rigid receiver motion, LOD changes and repeated scene teardown without detached marks or allocation growth. proof: `pnpm exec vitest run packages/core/__tests__/vq-bounded-decals.spec.ts`. + +### Phase 3 — Qualify the visible result + +- [ ] The impact sequence covers the 256-mark cap, moving receiver and LOD boundary on browser WebGPU. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-bounded-decals.playtest.json --url ${VQ_URL:?} --browser-recipe webgpu`. +- [ ] The same sequence runs on Linux native with matching pool/receiver observations and visible marks. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-bounded-decals.playtest.json --target desktop --executable ${VQ_NATIVE_EXECUTABLE:?}`. + +## Acceptance criteria + +- [ ] The supported receiver cases retain their marks under motion and teardown, and resource use is bounded independently of total shots fired. proof: the completed Phase 3 scenario outputs, with the named fixture, package/cohort and adapter recorded inline here. +- [ ] The feature preserves its documented inactive/fallback path and releases owned resources after repeated lifecycle transitions. proof: `pnpm exec vitest run packages/core/__tests__/vq-bounded-decals.spec.ts` plus the Phase 3 lifecycle scenario. + +## Performance and promotion + +Measure draw calls and geometry bytes at the cap. Batch only compatible marks when it improves the measured cost; do not trade correctness for an advertised one-draw system. Numerical targets are proposed acceptance targets, not benchmark results. Pin the fixture, metrics and thresholds before changing the implementation; never relax a failing threshold just to mark this PRD complete. Shared abstractions must pass the repository's reuse/LOC admission rule. Appearance remains editable source. + +## Blocked on + +Skinned/deforming receivers require a separate demand-backed extension and are not silently treated as rigid meshes. + +## Completion record + +Update the phase boxes and this PRD only after the named proof runs. Record actual results inline, including any remaining exclusions. A merged planning or implementation PR alone is not proof that every acceptance criterion passed. Archive according to the parent PRD filing rules when the work is genuinely complete. diff --git a/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-12-transparent-effects-composition.md b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-12-transparent-effects-composition.md new file mode 100644 index 0000000000..35ce8b0598 --- /dev/null +++ b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-12-transparent-effects-composition.md @@ -0,0 +1,64 @@ +--- +prd_contract: v1 +--- + +# PRD-VQ-12 — Overlapping transparent effects have an explicit correct or bounded-approximate path + +**Status:** PROPOSED — 2026-10-01. No implementation or qualification is claimed. +**Batch:** [Visual quality execution batch](README.md). **Wave:** 3 / scene-gated transparency. +**Dependencies:** Coordinate attachment/history ownership with VQ-02 and PRD-455. Preserve existing alpha-cutout foliage behavior. + +## Grounding and intended outcome + +[packages/core/src/world-cells.ts](https://github.com/ThreeNativeHQ/threenative/blob/d72778382b134ef8763f58825cb4d4fd8cc0f6e3/packages/core/src/world-cells.ts) distinguishes blended scatter from alpha cutout because individual instances are not ordinarily sorted. This is not a lack of all transparency support. A demand-backed improvement must compare sorting, cutout/alpha hashing and an optional OIT route before adding another pass. + +**Outcome:** A deterministic scene of intersecting smoke cards no longer visibly changes just because emitter insertion order changes, while glass/transmission and foliage keep their explicitly chosen existing paths. + +## Design and ownership + +Use upstream supported sorting/alpha techniques first. If the fixture still demonstrates a material gap, admit a bounded weighted-blended OIT route for eligible nonrefractive effects, with independent accumulation/revealage attachments and explicit composition. This is an approximation, not physically exact multi-layer refraction. Define eligibility, color space, premultiplied alpha and depth semantics. Unsupported materials stay sorted or fail with a reason; never silently route refractive glass into a smoke approximation. + +Nonrefractive smoke/particle cards first. No universal hair/glass/water fix, depth peeling, arbitrary material substitution or new renderer backend. + +## Required behavior + +- Insertion-order permutations produce equivalent eligible-effect output within a declared floating-point tolerance. +- Opaque geometry occludes eligible effects; alpha zero is an identity and dense overlap remains finite. +- Water/transmission, cutout foliage and custom depth materials retain their original route unless explicitly admitted. +- Resize, MSAA changes, scene switch and temporal-history invalidation release/recreate the right attachments once. + +## Execution phases + +All proof paths below are **planned implementation targets**, not existing passing tests. Reuse an existing equivalent test or scenario after inspecting current code, and update the canonical proof path rather than adding a duplicate. Follow [EXECUTE.md](EXECUTE.md) for fixture setup, variables, review and repository gates. + +### Phase 1 — Eligibility and the smallest useful technique + +- [ ] Implement explicit material-route selection using the existing renderer and test the cheaper sorted/cutout controls. proof: `pnpm exec vitest run packages/core/__tests__/vq-transparent-effects-composition.spec.ts`. +- [ ] Only where needed, add bounded accumulation/composition for eligible effects with numerical alpha and order-permutation tests. proof: `pnpm exec vitest run packages/core/__tests__/vq-transparent-effects-composition.spec.ts`. + +### Phase 2 — Compose safely with the world + +- [ ] Integrate opaque depth, premultiplied color and the existing output graph without altering excluded materials. proof: `pnpm exec vitest run packages/core/__tests__/vq-transparent-effects-composition.spec.ts`. +- [ ] Cover target lifetime, resize, quality fallback and temporal-history invalidation for the admitted route. proof: `pnpm exec vitest run packages/core/__tests__/vq-transparent-effects-composition.spec.ts`. + +### Phase 3 — Qualify the visible result + +- [ ] The overlapping-effects scene passes order permutations, occlusion and exclusion checks on browser WebGPU. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-transparent-effects-composition.playtest.json --url ${VQ_URL:?} --browser-recipe webgpu`. +- [ ] The same material-route and composition cases pass on Linux native with no unsupported attachment fallback hidden. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-transparent-effects-composition.playtest.json --target desktop --executable ${VQ_NATIVE_EXECUTABLE:?}`. + +## Acceptance criteria + +- [ ] The technique materially improves the demonstrated artifact and stays within its declared cost; otherwise retain the simpler existing routes and record a decline. proof: the completed Phase 3 scenario outputs, with the named fixture, package/cohort and adapter recorded inline here. +- [ ] The feature preserves its documented inactive/fallback path and releases owned resources after repeated lifecycle transitions. proof: `pnpm exec vitest run packages/core/__tests__/vq-transparent-effects-composition.spec.ts` plus the Phase 3 lifecycle scenario. + +## Performance and promotion + +Record attachment bytes, fill rate and total effect cost. A 50-card stress fixture is a test, not a universal scene limit. Numerical targets are proposed acceptance targets, not benchmark results. Pin the fixture, metrics and thresholds before changing the implementation; never relax a failing threshold just to mark this PRD complete. Shared abstractions must pass the repository's reuse/LOC admission rule. Appearance remains editable source. + +## Blocked on + +A real overlapping-effects consumer is the admission gate. Correct multi-layer refraction and strand hair remain out of scope. + +## Completion record + +Update the phase boxes and this PRD only after the named proof runs. Record actual results inline, including any remaining exclusions. A merged planning or implementation PR alone is not proof that every acceptance criterion passed. Archive according to the parent PRD filing rules when the work is genuinely complete. diff --git a/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-13-cinematic-stage-integration.md b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-13-cinematic-stage-integration.md new file mode 100644 index 0000000000..e9a870b3be --- /dev/null +++ b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-13-cinematic-stage-integration.md @@ -0,0 +1,64 @@ +--- +prd_contract: v1 +--- + +# PRD-VQ-13 — Depth of field and motion blur are qualified optional stages, not a second camera pipeline + +**Status:** PROPOSED — 2026-10-01. No implementation or qualification is claimed. +**Batch:** [Visual quality execution batch](README.md). **Wave:** 3 / optional cinematics. +**Dependencies:** PRD-269 motion correctness and PRD-455 history/reset rules; VQ-02 output lifetime qualification. + +## Grounding and intended outcome + +Current upstream supplies [DepthOfFieldNode](https://threejs.org/docs/pages/DepthOfFieldNode.html); the repository already lists motion-blur/temporal stage names and velocity infrastructure. The missing work is coherent generated-source integration and qualification, not implementing blur mathematics from scratch. + +**Outcome:** A cinematic route changes focus between a near and far target and applies motion blur to actual moving world geometry without smearing a camera cut, the HUD or an explicitly excluded first-person viewmodel. + +## Design and ownership + +Reuse installed upstream nodes after verifying the pinned versions. Keep focus, bokeh scale, shutter controls and enablement in generated render source. Reuse scene depth and velocity; specify stage ordering relative to reconstruction, bloom and the single output transform. Focus distance uses the node API's documented world units, not an invented millimeter lens equation. Camera cuts and projection/size changes reset any history. Disabled stages allocate and dispatch nothing. + +One optional DOF stage and one velocity-driven motion-blur stage in an existing generated-source consumer. No sequencer editor, autofocus AI, camera-physics package or forced gameplay blur. + +## Required behavior + +- A depth-target fixture keeps the focus plane sharp while the out-of-focus region changes, rather than blurring the entire image. +- Stationary geometry under a stationary camera has no motion blur; a moving rig and instance use their real motion history. +- The HUD remains outside the world post graph, and viewmodel inclusion is an explicit game decision. +- Off/on, cut, resize and tier switching preserve a valid frame and bounded targets. + +## Execution phases + +All proof paths below are **planned implementation targets**, not existing passing tests. Reuse an existing equivalent test or scenario after inspecting current code, and update the canonical proof path rather than adding a duplicate. Follow [EXECUTE.md](EXECUTE.md) for fixture setup, variables, review and repository gates. + +### Phase 1 — Reuse the existing stage seams + +- [ ] Add generated-source factories for installed DOF and motion-blur nodes with documented controls and no duplicate scene pass. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-cinematic-stage-integration.spec.ts`. +- [ ] Validate depth, velocity, stage order and unsupported-camera/material conditions before installation. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-cinematic-stage-integration.spec.ts`. + +### Phase 2 — Make transitions and exclusions correct + +- [ ] Implement history resets and explicit HUD/viewmodel composition boundaries. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-cinematic-stage-integration.spec.ts`. +- [ ] Add focus-plane, stationary-motion and stage-off identity assertions plus repeated-toggle disposal checks. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-cinematic-stage-integration.spec.ts`. + +### Phase 3 — Qualify the visible result + +- [ ] The focus/motion/camera-cut route passes on browser WebGPU with effect-region image checks. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-cinematic-stage-integration.playtest.json --url ${VQ_URL:?} --browser-recipe webgpu`. +- [ ] The same optional stages and camera route pass on Linux native, including disabled-path parity. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-cinematic-stage-integration.playtest.json --target desktop --executable ${VQ_NATIVE_EXECUTABLE:?}`. + +## Acceptance criteria + +- [ ] Both effects respond to the intended depth/motion inputs and disappear cleanly when disabled; no new rendering pipeline is introduced. proof: the completed Phase 3 scenario outputs, with the named fixture, package/cohort and adapter recorded inline here. +- [ ] The feature preserves its documented inactive/fallback path and releases owned resources after repeated lifecycle transitions. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-cinematic-stage-integration.spec.ts` plus the Phase 3 lifecycle scenario. + +## Performance and promotion + +Measure each stage independently. Keep optional/cinematic by default; no quality improvement is inferred from blur alone. Numerical targets are proposed acceptance targets, not benchmark results. Pin the fixture, metrics and thresholds before changing the implementation; never relax a failing threshold just to mark this PRD complete. Shared abstractions must pass the repository's reuse/LOC admission rule. Appearance remains editable source. + +## Blocked on + +Additional camera models and physical mobile performance are separate qualifiers, not assumed support. + +## Completion record + +Update the phase boxes and this PRD only after the named proof runs. Record actual results inline, including any remaining exclusions. A merged planning or implementation PR alone is not proof that every acceptance criterion passed. Archive according to the parent PRD filing rules when the work is genuinely complete. diff --git a/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-14-skin-material-qualification.md b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-14-skin-material-qualification.md new file mode 100644 index 0000000000..e4024ce504 --- /dev/null +++ b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-14-skin-material-qualification.md @@ -0,0 +1,64 @@ +--- +prd_contract: v1 +--- + +# PRD-VQ-14 — Skin shading reuses upstream material support and preserves facial animation + +**Status:** PROPOSED — 2026-10-01. No implementation or qualification is claimed. +**Batch:** [Visual quality execution batch](README.md). **Wave:** 3 / character-quality gate. +**Dependencies:** Use a license-clear rigged head. Preserve existing MetaHuman/GLTF binding and expression ownership. + +## Grounding and intended outcome + +Current upstream documents experimental [MeshSSSNodeMaterial](https://threejs.org/docs/pages/MeshSSSNodeMaterial.html). The prior audit's wording should not be read as absence of every subsurface-scattering primitive. Verify the installed pin; the product task is a controllable, portable skin look with real assets and explicit limits. + +**Outcome:** A rigged head retains expressions, normals and authored texture detail while thin regions respond plausibly to backlighting; the result is compared with its ordinary PBR baseline rather than declared AAA from an effect name. + +## Design and ownership + +Use the installed physical/SSS material or a supported upgrade, with appearance in generated source. Keep thickness, albedo, roughness, normal detail and artistic scattering controls asset/game-owned. Distinguish an approximate transmission term from a full diffusion model. Preserve skinning and morph-target paths and avoid counting the same lighting twice when probes or SSGI are active. No new mandatory core material class or MetaHuman-only render dependency. + +One textured, expression-capable head plus a synthetic thin-surface test. No offline path-traced skin, texture generation, pore synthesis, face-rig rewrite or claim that an approximate SSS node matches a production diffusion renderer. + +## Required behavior + +- The baseline and candidate share geometry, pose, exposure and lights; only the intended material route changes. +- Thickness-zero and disabled-scattering controls reduce to the declared baseline behavior. +- Expression/morph changes preserve texture bindings, tangent/normal continuity and independent character instances. +- A low tier has an explicit PBR fallback and does not fetch unused scattering assets. + +## Execution phases + +All proof paths below are **planned implementation targets**, not existing passing tests. Reuse an existing equivalent test or scenario after inspecting current code, and update the canonical proof path rather than adding a duplicate. Follow [EXECUTE.md](EXECUTE.md) for fixture setup, variables, review and repository gates. + +### Phase 1 — Admit the pinned material path + +- [ ] Implement the smallest generated-source skin route using compatible upstream support and declared thickness/texture inputs. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-skin-material-qualification.spec.ts`. +- [ ] Cover disabled/thickness controls, finite output and immutable borrowed asset data. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-skin-material-qualification.spec.ts`. + +### Phase 2 — Preserve the animated character + +- [ ] Exercise expressions, skinning and morph targets with the candidate material and existing lighting composition. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-skin-material-qualification.spec.ts`. +- [ ] Add an explicit low-cost fallback and scene/material lifetime checks across two independent head instances. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-skin-material-qualification.spec.ts`. + +### Phase 3 — Qualify the visible result + +- [ ] The neutral/backlit expression sweep runs on WebGPU with matched baseline/candidate captures and numeric control cases. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-skin-material-qualification.playtest.json --url ${VQ_URL:?} --browser-recipe webgpu`. +- [ ] The same head, expressions and generated material run on Linux native without feature loss or unexpected target errors. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-skin-material-qualification.playtest.json --target desktop --executable ${VQ_NATIVE_EXECUTABLE:?}`. + +## Acceptance criteria + +- [ ] The authored scattering controls are effective, facial animation remains correct, and the human reviewer can compare matched images without an automatic aesthetic score being invented. proof: the completed Phase 3 scenario outputs, with the named fixture, package/cohort and adapter recorded inline here. +- [ ] The feature preserves its documented inactive/fallback path and releases owned resources after repeated lifecycle transitions. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-skin-material-qualification.spec.ts` plus the Phase 3 lifecycle scenario. + +## Performance and promotion + +Report added shader/texture cost and frame contribution. Keep experimental/opt-in until the visual and platform evidence supports broader use. Numerical targets are proposed acceptance targets, not benchmark results. Pin the fixture, metrics and thresholds before changing the implementation; never relax a failing threshold just to mark this PRD complete. Shared abstractions must pass the repository's reuse/LOC admission rule. Appearance remains editable source. + +## Blocked on + +The owner supplies or approves redistribution rights for any third-party head. Human aesthetic approval is a named external checkpoint, not a falsely ticked test. + +## Completion record + +Update the phase boxes and this PRD only after the named proof runs. Record actual results inline, including any remaining exclusions. A merged planning or implementation PR alone is not proof that every acceptance criterion passed. Archive according to the parent PRD filing rules when the work is genuinely complete. diff --git a/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-15-hair-card-material-qualification.md b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-15-hair-card-material-qualification.md new file mode 100644 index 0000000000..63ff644019 --- /dev/null +++ b/docs/PRDs/batch-2026-10-01-visual-quality/PRD-VQ-15-hair-card-material-qualification.md @@ -0,0 +1,64 @@ +--- +prd_contract: v1 +--- + +# PRD-VQ-15 — Hair cards preserve coverage, tangent highlights and shadow behavior across quality tiers + +**Status:** PROPOSED — 2026-10-01. No implementation or qualification is claimed. +**Batch:** [Visual quality execution batch](README.md). **Wave:** 3 / character-quality gate. +**Dependencies:** Uses qualified temporal/alpha behavior from PRD-455; VQ-12 is optional and not assumed to solve hair. + +## Grounding and intended outcome + +Ordinary Three physical materials, anisotropy and alpha techniques are the first candidates. A dedicated strand renderer is not established as necessary by a manifest search. The bounded target is a license-clear hair-card asset that survives camera motion, lighting changes and native rendering. + +**Outcome:** A character's hair cards show authored directional highlights without losing silhouette coverage, sorting into obvious layers or casting an unrelated opaque block as their shadow. + +## Design and ownership + +Keep tangents, root-tip texture data, alpha thresholds, anisotropy and colors in generated materials. Prefer cutout/alpha-to-coverage or a qualified temporal technique when it preserves the asset. Do not silently use the smoke OIT approximation for hair, and do not promise order-independent physical scattering. Match visible and shadow alpha semantics. A low tier is an authored cheaper material/card representation, not an automatic deletion of random cards. + +Hair cards only, one rigged character asset and a synthetic crossed-card fixture. No procedural grooming, individual strands, hair simulation, multiple-scattering solver or new core material system. + +## Required behavior + +- Tangent and alpha inputs are validated; missing data has an explicit fallback or error. +- The synthetic test exercises crossed cards, back/front views, moving highlights and shadow silhouettes. +- Camera motion and quality switches are evaluated as frame sequences for coverage/flicker, not one screenshot. +- Two character instances keep independent materials where controls differ and share immutable assets safely. + +## Execution phases + +All proof paths below are **planned implementation targets**, not existing passing tests. Reuse an existing equivalent test or scenario after inspecting current code, and update the canonical proof path rather than adding a duplicate. Follow [EXECUTE.md](EXECUTE.md) for fixture setup, variables, review and repository gates. + +### Phase 1 — Coverage and directional shading + +- [ ] Implement a game-owned hair-card material from admitted upstream features with explicit alpha and tangent contracts. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-hair-card-material-qualification.spec.ts`. +- [ ] Add coverage, highlight-direction and visible/shadow agreement checks on the synthetic fixture. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-hair-card-material-qualification.spec.ts`. + +### Phase 2 — Integrate the real character and tiers + +- [ ] Apply the material to the rigged hair-card consumer without breaking skinning or borrowed resource ownership. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-hair-card-material-qualification.spec.ts`. +- [ ] Implement explicit lower-cost tiers and temporal/cutout compatibility with scene-switch disposal tests. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-hair-card-material-qualification.spec.ts`. + +### Phase 3 — Qualify the visible result + +- [ ] The moving-camera/head/light trace passes coverage and shadow checks on browser WebGPU with matched sequence review. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-hair-card-material-qualification.playtest.json --url ${VQ_URL:?} --browser-recipe webgpu`. +- [ ] The same hair asset and tier trace run on Linux native, reporting the actual alpha and temporal route. proof: `node packages/playtest/dist/runner/cli.js examples/abyss-framework/playtests/vq-hair-card-material-qualification.playtest.json --target desktop --executable ${VQ_NATIVE_EXECUTABLE:?}`. + +## Acceptance criteria + +- [ ] The supported hair-card path preserves silhouette and shadow coverage through motion and tier changes; no strand-renderer support is implied. proof: the completed Phase 3 scenario outputs, with the named fixture, package/cohort and adapter recorded inline here. +- [ ] The feature preserves its documented inactive/fallback path and releases owned resources after repeated lifecycle transitions. proof: `pnpm exec vitest run packages/create-threenative/__tests__/vq-hair-card-material-qualification.spec.ts` plus the Phase 3 lifecycle scenario. + +## Performance and promotion + +Record alpha overdraw, card triangles, shader cost and temporal artifacts by tier. A visually worse but faster thinning is not accepted as a quality fix. Numerical targets are proposed acceptance targets, not benchmark results. Pin the fixture, metrics and thresholds before changing the implementation; never relax a failing threshold just to mark this PRD complete. Shared abstractions must pass the repository's reuse/LOC admission rule. Appearance remains editable source. + +## Blocked on + +A redistributable hair-card asset and human visual approval are external requirements. Grooming and physical-device scaling remain separate. + +## Completion record + +Update the phase boxes and this PRD only after the named proof runs. Record actual results inline, including any remaining exclusions. A merged planning or implementation PR alone is not proof that every acceptance criterion passed. Archive according to the parent PRD filing rules when the work is genuinely complete. diff --git a/docs/PRDs/batch-2026-10-01-visual-quality/README.md b/docs/PRDs/batch-2026-10-01-visual-quality/README.md new file mode 100644 index 0000000000..a8c8fda8f3 --- /dev/null +++ b/docs/PRDs/batch-2026-10-01-visual-quality/README.md @@ -0,0 +1,75 @@ +# Visual quality execution batch — 2026-10-01 + +**Purpose:** close the functional gaps that most visibly affect ThreeNative games, without rebuilding working engine systems or turning a visual audit into a second renderer. + +**Contents:** 15 new bounded PRDs, 10 existing canonical execution owners in [EXISTING-PRDS.md](EXISTING-PRDS.md), companion-work links, and an [agent execution handoff](EXECUTE.md). Existing PRDs intentionally remain at their canonical paths; this folder is the single queue, not a second copy of their status/evidence. + +**Baseline:** `ThreeNativeHQ/threenative` `develop` at [d72778382b134ef8763f58825cb4d4fd8cc0f6e3](https://github.com/ThreeNativeHQ/threenative/commit/d72778382b134ef8763f58825cb4d4fd8cc0f6e3); Three is pinned to 0.185.1. Reconcile against current `origin/develop` before each task. This is a planning snapshot, not a runtime qualification report or an exhaustive fresh line-by-line audit. + +## Agreement with the audit, with corrections + +The visual priorities are useful. Several literal absence claims were too broad: + +- Current upstream has tiled/clustered lighting, volumetric material, DOF, additive animation and experimental skin-material primitives. Verify the installed pin and prefer integration/qualification over replacing them. Their existence upstream is not proof they are shipped in ThreeNative. +- [PR #375](https://github.com/ThreeNativeHQ/threenative/pull/375) and [PR #382](https://github.com/ThreeNativeHQ/threenative/pull/382) are merged. GPU-driven open-world work and rain/snow are not new greenfield tasks. Their remaining limitations must be separated from their completed work. +- A target-based compressed-asset guard remains in [build.ts](https://github.com/ThreeNativeHQ/threenative/blob/d72778382b134ef8763f58825cb4d4fd8cc0f6e3/packages/create-threenative/src/build.ts#L140-L202), but V8 alone does not prove Basis/Meshopt/Draco work in a packaged Android app. VQ-01 repairs and tests the complete capability contract rather than simply deleting the guard. +- The merged snow PR reports native bloom blanking the world. VQ-02 starts by reproducing that report; it does not pretend the root cause has already been found. +- Existing velocity and diffuse-probe source are not greenfield even though their older PRDs still say PROPOSED. Reconcile the proof, not just the headings. Likewise, animation crossfades exist, but the previous broad claim of interruption correctness must be tested for rapid reversals and returning to an already weighted action. +- Static probe relighting, texture residency, OIT, skin and hair are **gated extensions**, not mandatory replacements. No Lumen/Nanite/DLSS/Unreal-parity label is awarded by this folder. + +## First execution wave + +Start VQ-01 and VQ-02 independently. In parallel, qualify the unresolved PRD-269 motion/history cases. Then prioritize PRD-455 temporal reconstruction, PRD-339 exposure and PRD-460 visible prop transitions. For a character-heavy game, VQ-04/VQ-05 can run as a separate sequence; for reflective interiors, VQ-03 is the next lighting task. + +| Wave | New PRD | Player-visible outcome | Main dependency | +|---|---|---|---| +| 0 / correctness | [VQ-01](PRD-VQ-01-native-asset-capabilities.md) | Native asset compatibility follows the selected runtime and actual decoders | Selected runtime/cohort truth | +| 0 / correctness | [VQ-02](PRD-VQ-02-native-postprocessing-parity.md) | A requested post-processing stage never turns the native world into a blank frame | Reproduce reported native bloom failure | +| 1 / lighting | [VQ-03](PRD-VQ-03-local-reflection-probes.md) | Off-screen specular reflections come from a complete local probe | PRD-381 local-probe child; existing SSR | +| 1 / character motion | [VQ-04](PRD-VQ-04-locomotion-blend-spaces.md) | Locomotion blends by speed and direction without restarting its gait | Existing animation/stride player | +| 1 / character motion | [VQ-05](PRD-VQ-05-masked-additive-animation.md) | Upper-body actions and additive reactions compose over locomotion | Coordinate with VQ-04; IK ordering | +| 2 / scalable lighting | [VQ-06](PRD-VQ-06-many-local-lights.md) | Many local lights use a qualified upstream tiled or clustered path | Installed upstream pin; PRD-457 for shadows | +| 2 / atmosphere | [VQ-07](PRD-VQ-07-volumetric-fog.md) | Local volumetric fog composes with depth, lights and existing atmosphere | Existing atmosphere/kit and upstream volume path | +| 2 / atmosphere | [VQ-08](PRD-VQ-08-clouds-and-overhead-transmittance.md) | Clouds and their ground attenuation share one authored field | Merged rain kit; PRD-381 overhead field | +| 3 / gated GI extension | [VQ-09](PRD-VQ-09-incremental-diffuse-relighting.md) | Diffuse probes refresh bounded changed regions without a visible half-bake | Qualify PRD-268 first | +| 3 / memory-gated | [VQ-10](PRD-VQ-10-texture-mip-residency.md) | Texture residency releases real GPU memory rather than only biasing sampling | PRD-454 resource accounting; VQ-01 | +| 2 / high-payoff detail | [VQ-11](PRD-VQ-11-bounded-decals.md) | Impact and environment decals use a bounded portable lifecycle | Existing hit/base-geometry path | +| 3 / scene-gated transparency | [VQ-12](PRD-VQ-12-transparent-effects-composition.md) | Overlapping transparent effects have an explicit correct or bounded-approximate path | Demonstrated overlap artifact; temporal/output contract | +| 3 / optional cinematics | [VQ-13](PRD-VQ-13-cinematic-stage-integration.md) | Depth of field and motion blur are qualified optional stages, not a second camera pipeline | PRD-269/455; VQ-02 | +| 3 / character-quality gate | [VQ-14](PRD-VQ-14-skin-material-qualification.md) | Skin shading reuses upstream material support and preserves facial animation | License-clear animated head; upstream material | +| 3 / character-quality gate | [VQ-15](PRD-VQ-15-hair-card-material-qualification.md) | Hair cards preserve coverage, tangent highlights and shadow behavior across quality tiers | Hair-card fixture; temporal/alpha qualification | + +The ten reused owners are **269, 455, 339, 460, 456, 457, 344, 268, 341 and 342**. Their full paths, residual work and companion PRDs are in [EXISTING-PRDS.md](EXISTING-PRDS.md). Read it before starting either a new or reused item. PRD-341 is now implemented and archived by [PR #392](https://github.com/ThreeNativeHQ/threenative/pull/392); reuse its tone gate rather than reopening that work. + +## Dependency outline + +```mermaid +flowchart TD + A[VQ-01 native asset capabilities] --> T[VQ-10 texture residency] + B[VQ-02 native output regression] --> U[PRD-455 temporal reconstruction] + V[PRD-269 motion/history qualification] --> U + B --> E[PRD-339 auto exposure] + U --> C[VQ-13 cinematic integration] + L[PRD-460 prop transitions] --> H[PRD-456 distant proxies] + W[VQ-04 locomotion] --> M[VQ-05 masked additive layers] + P[PRD-268 diffuse qualification] --> G[VQ-09 incremental relighting] + F[PRD-454 resource accounting] --> T +``` + +These arrows are actual integration dependencies, not a claim that all independent features must wait for the entire preceding wave. Shared render and world files still require reconciliation before merging. + +## Scope and admission rules + +The deliverable is a **visible result with a lifecycle and a qualified platform path**, not a class name or an `applied` marker. Retain ordinary Three.js APIs. Shader/material choices, fog/cloud appearance, camera controls and animation state choices stay generated game source. Shared core code is limited to justified mechanisms. No animation graph editor/IR, new scene format, ECS, second frame loop or global material package is authorized. + +Numbers in new PRDs are proposed fixture targets and must be pinned before implementation; none are measured results. Use matched input routes, the same adapter/cohort and separate CPU, GPU and presented-cadence observations. Effect-region and temporal-sequence checks complement human visual review; they do not replace it with an invented score. + +No implementation is included. Open **one implementation PR per canonical PRD** when executing it; this collection's planning PR is not an umbrella implementation PR. Keep existing work and evidence intact and archive through the repository's established PRD lifecycle. + +## Upstream references checked during filing + +- [Tiled lighting](https://threejs.org/docs/pages/TiledLightsNode.html), [clustered lighting](https://threejs.org/docs/pages/ClusteredLightsNode.html), [dynamic analytic lights](https://threejs.org/docs/pages/DynamicLightsNode.html). +- [Temporal AA](https://threejs.org/docs/pages/TRAANode.html), [depth of field](https://threejs.org/docs/pages/DepthOfFieldNode.html), [decal geometry](https://threejs.org/docs/pages/DecalGeometry.html). +- [Volume material](https://threejs.org/docs/pages/VolumeNodeMaterial.html), [experimental skin material](https://threejs.org/docs/pages/MeshSSSNodeMaterial.html). + +These links describe current upstream, not necessarily the pinned 0.185.1 distribution. Pin/patch compatibility is part of admission.