Planar water: the mirror pass, built and inert behind a dev lever
A second camera on the far side of the water plane, rendering into a half-viewport target that `enhanced_water.wgsl` reads BENEATH the screen-space march — so SSR still wins wherever it finds something, and the mirror only fills the hole SSR cannot reach: the ray leaving the screen, and the top-edge fade, which is exactly where a shallow-angle lake wants its far bank. **It does not work yet, and it is not offered to anyone.** The mirrored eye sits as far below the surface as the real eye sits above it — 26 yd down on Lake Everstill — which is inside the lake bed, so the pass must clip at the water plane or it renders sand. The clip is implemented (Lengyel, adapted to this client's reverse-Z, around a finite far plane because the oblique row makes depth affine and an infinite far collapses every distant fragment onto one value) and it is WRONG: the mirror comes back a radial smear. So this is `WOW_WATER_MIRROR=1`, a dev lever — no CVar, no row in Options. It graduates to both, like every other lane, once a capture shows a reflection instead of a starburst. What IS established, and is why this lands rather than waiting: - **With the lane off the water is byte-identical** to before the pass existed, verified against a `git stash`ed build of the same tree. - With it on it reaches the water and moves 63% of a lake frame — the plumbing, the binding, the uniform and the composite all carry. - Off, the plugin **registers nothing at all**, the posture `static_gx::enabled` takes. That is not tidiness: `drive_mirror` declares `ResMut<Assets<Image>>`, and merely registering it dormant added 59 undeclared orders to `Update` and tripped the schedule ratchet. Three things this cost, all of them now written into `docs/GRAPHICS.md` and all of them my own: 1. **The pipeline failed to compile for most of a session while every A/B read a clean zero.** The field is `clip_position`; `WaterFragment` has no `position`. Naga refused the shader, the water fell back to another path, and I measured the fallback over and over — including twice mistaking the lake bed seen through clear water for a working mirror. The client logs pipeline errors rather than panicking, by design, so the answer was in the log the whole time. **Grep the capture log for `error:` before believing any shader A/B.** 2. **A disabled lane is not automatically free.** Starting SSR's march from the fogged `reflection` instead of `sky` looked equivalent and moved 10.1% of a lake frame with the mirror switched off. The control that catches that is diffing lane-off against a stashed build — not against an older capture, which is what I reached for first. 3. **A flag colour has to be one the scene cannot produce.** My first three "every gate passes" measurements were counting the orange lake bed as my red flag, which sent the hunt in the wrong direction for an hour. The pass's own cost is deliberately unmeasured: it draws the scene a second time, so it is the first item on the programme that spends main thread, and pricing a broken render against item 1's view-distance table would mean nothing. That happens when the projection does. Verified: ALL GATES GREEN (591 s); `benilla-app --lib` against the install at the exact 269-failure baseline, set-identical by `comm`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgstFWtn1RxEJ5kVrpgYwn
This commit is contained in:
+30
-6
@@ -188,12 +188,36 @@ hold together (`REGISTERED`, `VideoConfig`, `WaterQuality::default`) plus the ru
|
||||
Medium keep Enhanced deliberately: free on the machine it was measured on is an argument for the
|
||||
default, not for the rung whose job is hardware that cannot afford what this one can.
|
||||
|
||||
**What a planar reflection would still add**, if it is ever wanted: the geometry SSR cannot see.
|
||||
The march gives up when the ray leaves the screen (`probe.z < 0.5`) and the result fades toward the
|
||||
top edge, which is exactly where a shallow-angle lake wants its far bank and trees. That is the
|
||||
real remaining gap — and unlike everything above it, a planar pass draws the scene a second time,
|
||||
so it is the first item on this list that costs **main thread**. Price it against the view-distance
|
||||
table in item 1 before building it.
|
||||
**The planar mirror — built, wired, and NOT yet working.** `benilla_world::liquid::reflect` is a
|
||||
second camera on the far side of the water plane, rendering into a half-viewport target that
|
||||
`enhanced_water.wgsl` reads *beneath* the screen-space march — so SSR still wins wherever it finds
|
||||
something, and the mirror only fills the hole where the ray leaves the screen.
|
||||
|
||||
Everything is in place and measured: with the lane off the water is **byte-identical** to before
|
||||
it existed, and with it on it visibly changes 63% of a lake frame. What is wrong is the **oblique
|
||||
near-plane projection**. The mirrored eye sits as far below the surface as the real eye sits above
|
||||
it — 26 yd down on Lake Everstill — which is inside the lake bed, so the pass has to clip at the
|
||||
water plane or it renders sand. The clip is implemented (Lengyel, adapted to this client's
|
||||
reverse-Z) and it is wrong: the mirror comes back a radial smear.
|
||||
|
||||
So it is a **dev lever, `WOW_WATER_MIRROR=1`, not a CVar and not a row in Options.** It graduates
|
||||
to both, like every other lane here, once a capture shows a reflection instead of a starburst. The
|
||||
next step is the projection and nothing else.
|
||||
|
||||
Two things this cost, both worth not repeating:
|
||||
|
||||
- **The pipeline failed to compile for most of a session and every A/B read a clean zero.** The
|
||||
field is `clip_position`, not `position`, and `WaterFragment` has no `position` — so naga
|
||||
refused the shader, the water fell back, and the measurements were all of the fallback. The
|
||||
client logs pipeline errors rather than panicking (`gpu: wgpu errors are logged, not fatal`), so
|
||||
**grep the capture log for `error:` before believing any shader A/B.**
|
||||
- **A disabled lane is not automatically free.** Changing SSR's base from `sky` to the fogged
|
||||
`reflection` moved 10.1% of a lake frame with the mirror switched off. The control that catches
|
||||
it is diffing the lane-off render against a `git stash`ed build, not against an older capture.
|
||||
|
||||
The cost of the pass itself is unmeasured, because measuring a broken render would mean nothing.
|
||||
It draws the scene a second time, so it is still the first item on this list that spends **main
|
||||
thread**, and it gets priced against item 1's view-distance table before it is offered to anyone.
|
||||
|
||||
### 4. Froxel volumetrics
|
||||
|
||||
|
||||
Reference in New Issue
Block a user