Repository navigation
docs(prds): PRD-561 decline contact shadows from screen depth - #480
Conversation
Add the Bend screen-space-shadow port to core as mechanism: the CPU dispatch builder (contact-shadow-dispatch.ts, Apache-2.0, with a spec that emulates every thread) and the TSL compute kernel (contact-shadow.ts) behind contactShadow(). The chain gains a contactShadows stage name before ambientOcclusion. THIRD_PARTY_NOTICES.md ships in the package. The builder rounds the light to float32 and measures bounds from floor(light), the pixel the kernel measures from. The upstream round() left column 1919 unwritten for a light at x = 38400 on a 1920-wide target. The kernel has not run on a GPU yet; PRD-561 box 2 and the stage wiring follow.
… blob Both the starter and the platformer gain src/render/contactShadowStage.ts, a chain stage (minimumTier medium) that multiplies the screen-space contact mask from @threenative/core into the frame. The look (reach, contrast, strength per tier) lives in that generated file; the dispatch and kernel stay in core. The platformer drops its painted blob mesh and the `drop` pose field. The scaffold keeps the render-folder import ban with one exact-string exemption for the contactShadow import, mirrored in the core-boundary allowlist. The fox rig floats 0.05 to 0.2 m above its capsule bottom, which the blob used to mask; the convention test now states that bound. Proof: contact-shadow.playtest.json on the RTX 2080 (webgpu recipe) passes with the stage on and fails with it off; the same scenario passes on a scaffolded starter.
…ing and silhouettes Final tried state of the template stage before Phase 2 is withdrawn: the view space comes from the pass camera's projection inverse (the post quad's camera made every rebuilt normal flat), the term applies only on sun-facing pixels and not across silhouettes. Two fresh visual judges still returned REGRESSION. Kept in history so the follow-up can start from it.
…o REGRESSION judge verdicts Two fresh visual judges returned REGRESSION on the platformer (the stage did not beat the control with the blob removed). The templates, the core-boundary allowlist additions and the platformer playtest go back to the Phase 1 state. The WGSL flag-index fix in contact-shadow.ts stays: it is a kernel bug found on a GPU, independent of the template wiring. The stage source is kept in 4afd70c and PR #480 for the follow-up.
…s blocked The contact-shadow stage built and ran on a GPU, and failed the visual judge twice on the platformer. The PRD keeps every box open with the reason, adds the measured cause (4096 key-light shadow map over 44 m already resolves the foot gap), the pass-camera projection-inverse finding and a Blocked-on list.
Visual judge: two rounds, both REGRESSION (Phase 2 not shipped)Pose: platformer start, fox standing. Headed, Round 1 ( Full frame, round 2, run 1: BEFORE · CONTROL · AFTER All 48 frames (feet, castle, islands, full; two runs) are on the |
…he unused mechanism One falsifier round with the key-light map cut to 1024 over 44 m (about 4.3 cm a texel) judged REGRESSION: the feet were pixel-identical between CONTROL and AFTER and the stage added speckle on tower rims and silhouettes. Nothing consumes contactShadow(), so the kernel, the dispatch builder, their spec, the capability entries, the CHARTER paragraph and the third-party notice go back to their pre-PRD state. The code stays recoverable at 9bd6b3c, c9773d9 and 4afd70c on this branch. The PRD moves to done/ as DECLINED with the evidence URLs and the untested far-field threshold.
Resolves the batch README table: PRD-567 and PRD-561 both link to done/.
Falsifier round: 1024 key-light map (about 4.3 cm a texel), REGRESSION, PRD declinedSame platformer pose, headed Feet: BEFORE · CONTROL · AFTER The PRD moved to |
|
UNJUDGED artifact-fix candidate — parked; the existing decline remains. Candidate d93319599 stays on the separate experiment branch. It reduces trace reach to 8/6 pixels, contrast to 1, and gates application by measured sun-shadow texel size. It suppresses the effect on these poses and leaves a fox ear dash; useful grounding has not been demonstrated. No candidate code was integrated into this PR. The author’s earlier “NEUTRAL by measurement” inference is retracted: pixel differences cannot provide a visual-judge verdict. These comparisons are UNJUDGED. The requested Claude Code visual-judge skill is unavailable; no substitute judge ran and no acceptance box changed. CONTROL = 4afd70c with the stage disabled; AFTER = candidate enabled. BODY_REST=0.377 in both; map size differs only between the 1024/4096 sets. Each sheet has CONTROL left, AFTER right, run 1 above run 2. All eight run metadata files confirm NVIDIA/Turing WebGPU, headed Chromium, 1280×720. Labels are burned into the images.
All original labeled frames and capture metadata. Checks: 26 dispatch/template-look tests pass; scaffold byte-stable test and stage-file Biome pass. The existing contact-shadow scenario passes with the stage and fails its stage-presence assertion without it; that proves wiring, not grounding. Root typecheck/lint/full suite, native proof and GPU cost remain unrun. No merge, ready, archive or deployment. The normal pre-push drift hook stopped because this historical experiment checkout lacks Quarantine: experiment source commit |
…ct-shadows # Conflicts: # docs/PRDs/unreal-source-borrowing/README.md












What is this PR about?
PRD-561 is declined, so the planned soft shadow under feet and small objects will not ship. The engine and the games do not change. The platformer keeps its flat disc under the fox.
Why does it matter?
Small objects and feet do not look grounded, because no shadow shows where they touch the ground. The plan was to add that shadow. In the judged test poses on the platformer camera, 0 of 3 showed the feet touching the ground. Low-resolution light maps also added noisy dots to the image. Keeping the plan open keeps it on the list with no path to ship.
What changed
docs/PRDs/done/withStatus: DECLINEDand its decision record.docs/PRDs/unreal-source-borrowing/is removed.README.mdlinks to the new location.How I checked it
git diff --name-only origin/develop...HEAD | grep -v '^docs/'prints nothing. The branch changes only docs.8eb1159c7deleted the mechanism code. The diff againstdevelophas no code.pnpm check:docsexits 0. It checked 3029 relative links in 1350 Markdown files.check-doc-links,evidence-budget,evidence-citations,sync-agent-docs,ci-structureandci-needs. 246 tests pass.git cat-file -t).develop(b753d2013). The only conflict was the README row.Still open
The decline closes these items without running them:
No box is ticked for work that did not run.
Where to look first
docs/PRDs/done/PRD-561-contact-shadows-from-screen-depth.md, lines 1 to 12: the status and the decision.PRD progress: 25% — 0/3 phases (1/4 boxes), 0/3 acceptance (generated)
PRD:
docs/PRDs/done/PRD-561-contact-shadows-from-screen-depth.mdPhase 1: Mechanism and the apply decision — 1/2
## Decisions). proof:pnpm exec vitest run packages/core/__tests__/contact-shadow-dispatch.spec.ts— Evidence: 7 passed (1920x1080, 1001x577, 63x65, 1x1, 130x70, 1024x512, six light placements each; bounds case 301,203 to 700,510).## Decisions. proof:pnpm visuals:ab --before <arm A> --after <arm B> --raters 3on the starter and the dark-environment fixture.Phase 2: Templates use it — 0/1
pnpm test:templates.Phase 3: Native — 0/1
pnpm parity --target desktop --only-tests contact-shadow.Acceptance criteria
node packages/playtest/dist/runner/cli.js playtests/contact-shadow.playtest.json --url <dev url> --browser-recipe webgpuwith aregionminDarkPixelRatioassertion — Evidence: open. Arm A at this camera scale did not produce it; two judge rounds REGRESSION (see## Decisions).TN_FRAME_BUDGETp50 delta, stage on against stage off, fromnode packages/playtest/dist/runner/cli.js perf— Evidence: open. Informal gpuCompute 0.1 to 0.2 ms; theperfp50 delta was not run on a shipped stage.lowtier refuses it by name. proof:node packages/playtest/dist/runner/cli.js perf --logcat <serial>stage on against stage off — Evidence: open. Physical device, no shipped stage to measure (see## Blocked on).