Skip to content

Shadow material casters - #134

Merged
nnewson merged 2 commits into
mainfrom
shadow-material-casters
Aug 4, 2026
Merged

Shadow material casters#134
nnewson merged 2 commits into
mainfrom
shadow-material-casters

Conversation

@nnewson

@nnewson nnewson commented Aug 4, 2026

Copy link
Copy Markdown
Owner

No description provided.

nnewson added 2 commits August 4, 2026 12:13
The shadow fragment path could not apply the visible material's alpha
mask, and the pipeline front-culled even double-sided materials. Both
were visible in ShadowLodDemo: the alpha-masked cutout cast a solid
rectangle, and the double-sided sheet — authored face-on to the sun —
cast nothing at all, because cullMode = eFront discarded the only faces
it had.

The item asked for four shadow material modes. They land as two
pipelines, not four: only the alpha half needs a different fragment
shader, and the sidedness half is dynamic cull state the shadow
pipelines had never used.

- ShadowCasterAlpha (Opaque / Masked), classified once at the object
seam by shadowCasterAlpha(const Material&) and stored once, on
ShadowGeometryRequest::alpha. Both consumers read that one field — the
resolver to pin a cutout to full detail, the pass to pick its fragment
path — so they cannot disagree about what a caster is. Defaults to
Masked: the pessimistic answer costs a fetch and says so in the panel,
while the optimistic one silently restores the solid rectangle. BLEND
maps to Opaque deliberately; its shadow semantics remain an open design
decision.
- shadow_masked.frag + self_shadow_second_masked.frag apply the cutout
from the bindless material authority via
ShadowPushConstants::materialIndex. The masked second self-shadow layer
is not optional: a cutout whose first layer masks and whose second does
not self-shadows through its own holes.
- One implementation of the cutout test. shaders/material.glsl now owns
the material block, the UV/transform helpers and the alpha test, and
shader.frag calls them too, so forward and shadow agree by construction.
Four shared includes were extracted with it; Materials and
ShadowPushConstants are now guarded blocks, and the push struct gained
offsetof asserts.
- Dynamic cull mode on every shadow pipeline, set per draw from an
explicit per-family ShadowFaceCull policy. PerCaster is what fixes the
sheet. The self-shadow first pipeline disappeared: it differed in cull
mode alone.
- Bindless is set 2 in every pipeline that opts in — a bindless-without-
globals config gets an empty set-1 layout, since sets must be
contiguous.
- Alpha-masked shadow LOD begins at level 0, reported as
AlphaMaskedFallback with an infinite projected error and no hysteresis
history. No simplifier channel measures where a binary alpha boundary
lands, so a coarser policy needs a silhouette-error argument first.
Forgot to fetch main before the new branch.

No code conflicts, but documentation.  One of which included
measurements.  Had to re-verify the get the new correct values (which
were different from either individual branch)
@nnewson
nnewson merged commit 18c2b29 into main Aug 4, 2026
4 checks passed
@nnewson
nnewson deleted the shadow-material-casters branch August 4, 2026 12:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant