Repository navigation
glass: the shadow comes from the merged field in the shader - #1137
Conversation
Signed-off-by: fizzy pop-os-claude-1 <slot+pop-os-claude-1@fizzy.invalid>
|
TRIAGE @0dc54145 auto: mechanical rules met (fizzy-* app author, names work#980, 185 non-test lines <= 400, no risky path). Labelled |
Where this PR standsStage: Author's turn What the PM needs before approving (ticks as it is met; the full CI runs only at the end, after the reviews are clean):
Reviews at the current commit (
4 earlier reviews are for older commits and will be redone. Updated 2026-11-06 14:39 UTC by the PM. This comment is edited in place. |
|
Follow-ups: |
Signed-off-by: fizzy pop-os-claude-1 <slot+pop-os-claude-1@fizzy.invalid>
|
Rework published. |
glass: joined glass casts one shadow, drawn by the glass itself
In plain words
Floating glass controls, such as the demo player's buttons or a row of bubbles over a canvas, each drew a dark ring round themselves as a shadow. Where two bubbles run together into one piece of glass, those rings overlapped. They left a darker band across the bridge between the bubbles, and drew a second shadow round a drop sitting inside a bar. Now the glass casts one soft shadow from its joined outline. It has no seams and no double darkness, and it costs no extra drawing.
What changes
What you will notice
Bubbles that run together, such as the demo transport's buttons, now have one shadow round the joined shape. The dark band across their bridge is gone, and so is the second ring round a button sitting inside a bar. A single bubble on its own looks the same as before.
How we know it works
New tests check the shadow on the processor, using the same arithmetic as the glass program. They fail on
main, where the shadow does not exist yet:How this serves fizzy
Glass is one material with a single shadow, as real glass has, and it costs fewer draws (Materials).
For agents: technical summary
Goal
Replace the per-item shadow rings of a
core.glasslayer (anddialogs.glassBubbles), each aliquid_glass.drawShadowmesh, with one shadow computed by the liquid glass program from the joined outline. The punch pass writesdst·(1−a)and the add pass addso·cov. Witha = cov + (1−cov)·sh, the result isglass·cov + dst·(1−cov)·(1−sh): a black shadow outside the glass only, in passes that already run.What changed and why
LiquidField:Shadow { alpha, fade_px, offset }and ashadowfield.Uniforms.shadowis vec4 11 ={fade_px, offset.x, offset.y, alpha}, soheader_vec4sgoes 11 → 12 anduniform_vec4s= 60 (the backends' cap is 64).packfills it, and leaves it 0 when alpha < 0.002, fade < 0.5 px, or anedgeis set.withReach(and soboundsand the cluster quads) grows byfade_px + max|offset|when the shadow is on.G 12;outlineAt(q, first, count)gives the two nearest shape distances (sdRoundBox, orpanelDistancefor the panel slot), joined bysmin, without the place term.shfollows drawShadow'sa·(1−x)²falloff from the outline moved by the offset, scaled by the blended lens. The program discards only whencov <= 0 && sh <= 0.002. The punch returnscov + (1−cov)·sh, and the add pass keepsif (cov <= 0) discard.outlineAtandshadowAt.Sample.shadowis set fromsampleWith;shadowAtis split out to keepsampleWithunder lint's 150-line limit.core/glass.zig: the ring loop andrecord.shadow/shadow_shapesare deleted.newFieldsets.shadowfromdialogs.surfaceShadow(): alpha ×opts.shadow, fade and offset × scale. The clip cull adds the shadow's reach (none with an edge). The "30 items" test now asserts that each field carries the alpha.core/dialogs.zigglassBubbles: passes.shadow = opts.shadowto the layer and keeps its rings only on the fallback path (!layer.active()).tests/integration.zig: the@sizeOf(LF.Uniforms)pin goes from 11 to 12 header vec4s.Cost: the shadows take 0 draws; before, they took one mesh per item. The skirt pixels, the band the quad grew by
fade + offset, run the punch loop plus onesdRoundBoxper shape inoutlineAt, then the add pass discards them. The P0 glass bench measures this.How it was verified
scripts/zb build test(211/211 steps),scripts/zb build test-integration(103/103 steps),scripts/zb build,scripts/zb build lint,scripts/zb build check-webandzig fmt --checkpass locally on Linux. The newliquid_field_tests.zigtests fail onmain, which has noSample.shadow. Not seen on screen.Not done / follow-ups
compiled/{glsl,msl,spv,dxil}) must be regenerated withscripts/compile-shaders.sh. The worker sandbox refused to runshadercross, so they were not regenerated in this change; see the report. Until they are, the compiled programs read the old 11-vec4 header and the glass draws wrong.Part of fizzyedit/work#980