Translucent coloured shadows: alpha-blend casters tint and attenuate light (stained glass) #212

Closed
opened 2026-09-30 21:16:57 +00:00 by sky_line · 0 comments
Owner

Today alpha-blend casters either cast a stippled hard shadow at a 0.5 alpha cutoff (non-rigged), or no shadow at all (rigged avatar alpha-blend). Both are wrong for glass, tinted windows, sheer cloth and similar.

Goal

Light through a translucent caster is attenuated by its opacity and tinted by its colour:

  • More alpha: darker shadow. Less alpha: lighter shadow.
  • Coloured glass casts coloured light, so stained-glass windows throw colourful patterns.

Shadow-map path (sun cascades and projector atlas)

  • Translucency map: add one per cascade/tile, RGBA8 or RGB10A2 cleared to white. Alpha-blend casters render into it with multiplicative blending (dst *= mix(1, colour, alpha)), writing no depth.
  • Depth test: the translucency pass depth-tests against the opaque shadow depth, so glass behind a wall doesn't tint.
  • Transmittance-behind-caster depth: keep the nearest translucent depth, so receivers in front of the glass aren't tinted.
  • Lookup: light = opaque_visibility * (receiver_depth > translucent_depth ? transmittance.rgb : 1).
  • Mask casters: stay in the opaque depth map, alpha-tested as now.
  • Rigged avatars: "Full" in RenderAvatarShadowDetail puts rigged alpha-blend into the translucency pass.

Ray-traced path (RenderVKSunShadows 2, RT projectors)

  • Ray type: switch the shadow ray query from a terminate-on-first-hit visibility test to a transmittance ray. Candidate hits on translucent instances multiply the throughput by the texel's tinted transmittance, and the ray terminates on an opaque hit or when throughput falls below about 0.01.
  • Ordering: order is irrelevant for multiplicative transmittance, so no sorting is needed.
  • Materials: reuse the shared candidate alpha test to fetch base colour and alpha.

Details

  • Transmittance colour = base colour x vertex tint, with an optional saturation boost setting.
  • Glow/fullbright surfaces don't emit light.
  • Cost: one extra colour target per cascade, drawing only the alpha-blend bucket. RT: extra candidate shading on translucent hits only.
  • Setting: RenderVKTranslucentShadows (on by default for High+), plus Lightbox exposure.

Related: #185, #194, #195.

Today alpha-blend casters either cast a stippled hard shadow at a 0.5 alpha cutoff (non-rigged), or no shadow at all (rigged avatar alpha-blend). Both are wrong for glass, tinted windows, sheer cloth and similar. ## Goal Light through a translucent caster is attenuated by its opacity and tinted by its colour: - More alpha: darker shadow. Less alpha: lighter shadow. - Coloured glass casts coloured light, so stained-glass windows throw colourful patterns. ## Shadow-map path (sun cascades and projector atlas) - **Translucency map:** add one per cascade/tile, RGBA8 or RGB10A2 cleared to white. Alpha-blend casters render into it with multiplicative blending (dst *= mix(1, colour, alpha)), writing no depth. - **Depth test:** the translucency pass depth-tests against the opaque shadow depth, so glass behind a wall doesn't tint. - **Transmittance-behind-caster depth:** keep the nearest translucent depth, so receivers in front of the glass aren't tinted. - **Lookup:** `light = opaque_visibility * (receiver_depth > translucent_depth ? transmittance.rgb : 1)`. - **Mask casters:** stay in the opaque depth map, alpha-tested as now. - **Rigged avatars:** "Full" in `RenderAvatarShadowDetail` puts rigged alpha-blend into the translucency pass. ## Ray-traced path (RenderVKSunShadows 2, RT projectors) - **Ray type:** switch the shadow ray query from a terminate-on-first-hit visibility test to a transmittance ray. Candidate hits on translucent instances multiply the throughput by the texel's tinted transmittance, and the ray terminates on an opaque hit or when throughput falls below about 0.01. - **Ordering:** order is irrelevant for multiplicative transmittance, so no sorting is needed. - **Materials:** reuse the shared candidate alpha test to fetch base colour and alpha. ## Details - Transmittance colour = base colour x vertex tint, with an optional saturation boost setting. - Glow/fullbright surfaces don't emit light. - **Cost:** one extra colour target per cascade, drawing only the alpha-blend bucket. RT: extra candidate shading on translucent hits only. - **Setting:** `RenderVKTranslucentShadows` (on by default for High+), plus Lightbox exposure. Related: #185, #194, #195.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sky_line/Slipstream#212
No description provided.