Inverted Normal Studio

Sharp Stencil Shadows

Documentation for Sharp Stencil Shadows, a URP renderer feature for hard, pixel-exact stencil shadow volumes.

Transparent and Translucent Casters

Home › Guides

Overview

A shadow volume only knows a mesh's shape, so on its own it casts a solid shadow even through texture holes or glass. Transparent Casters > Mode controls how alpha-clipped and transparent casters are handled instead.

How materials are classified

Classification uses standard URP material state:

  • Transparent: render queue above 2500, or Surface Type set to Transparent.
  • Alpha-clipped: render queue 2450 to 2500, or Alpha Clipping enabled.
  • Opaque: everything else.

What works with each light

Shadow Main light Point and spot lights
Cutout holes Textured Textured
Partial shadows Uniform Opacity, Textured Local Light Transmittance, on Sharp Stencil Shadows/Lit receivers
Colored shadows Textured per texel, Uniform Opacity per material; in URP Lighting, with Colored Transmittance Local Light Transmittance, on Sharp Stencil Shadows/Lit receivers

The one custom shader

Colored and partial point and spot light shadows need receivers using Sharp Stencil Shadows/Lit. Colored sun shadows work on stock URP shaders, but are exact only on it. Everything else works the same with stock URP shaders. See below.

Transparent caster modes

Mode Alpha-clipped casters Transparent casters Cost
Off Solid shadow Solid shadow None
Uniform Opacity Solid shadow One partial, tinted shadow from the base color Its volume plus a few scissored passes per caster
Textured (default) Holes follow the alpha test Per-texel opacity and color Scene depth, and a caster atlas redrawn each frame

Textured mode needs scene depth. On renderers in Tile-Only Mode it falls back to Uniform Opacity, with one diagnostic.

Renderers with mixed materials

  • Textured: any alpha-clipped or transparent submesh sends the whole renderer to the caster atlas, so a tree with clipped leaves or a car with windows casts correctly.
  • Uniform Opacity: only renderers whose submeshes are all transparent cast a partial shadow. Mixed renderers cast solid shadows.

Switching at runtime

StencilShadowRendererFeature.FindActive()?.SetTransparentCasterMode(TransparentCasterMode.UniformOpacity);

Alpha-clipped (cutout) casters

In Textured mode, cutout casters are drawn into the caster atlas with their material's own ShadowCaster pass. Custom alpha tests and vertex animation in that pass shape the shadow. Materials without one, such as URP Unlit, use a replacement pass that reads the base map, base color, cutoff, and culling.

The material's culling is followed: a double-sided card casts from both sides, and a one-sided card facing away from the light casts nothing.

Colored translucent shadows

A transparent layer with alpha a and linear color c lets sqrt(1 - a*a) * pow(c, a) of the light through in each channel: all of it at a = 0, none at a = 1, tinted by the surface color in between.

  • Uniform Opacity evaluates this once per material from Base Color.
  • Textured evaluates it per texel from Base Map multiplied by Base Color.

Overlapping transparent shadows multiply, and a transparent shadow never darkens an opaque shadow further.

Colored transmittance for the sun

In URP Lighting mode, URP's shadow input is a single value, so by default a glass shadow from the sun is neutral grey at the transmitted brightness. Colored Transmittance (off by default) tints it by the transmitted color.

  • Sharp Stencil Shadows/Lit receivers tint only direct sunlight, so ambient light, other lights, reflections, and emission keep their color.
  • Stock receivers get a tint weighted by an estimate of sunlight against ambient light. It is exact for surfaces lit only by the sun, and softer where ambient light is strong. It can't separate lightmaps, local light probes, other lights, reflections, emission, or normal maps, so those can differ from the shader's result.

It costs nothing when no transparent caster shadows the sun in view. Otherwise it adds one screen-sized RGBA8 texture and one multiply pass.

Point and spot lights

Cutout holes

In Textured mode, cutout and transparent casters within a shadowed light's reach get a perspective tile in a second caster atlas, drawn from the light's position with the material's ShadowCaster pass. Holes then appear in the light's shadow on every lit shader. Casters very close to the light, or that don't fit in the atlas, cast from their volume instead.

Colored and partial shadows

URP's lit shaders take a single, binary shadow value per point or spot light, so transparent-only casters cast no point or spot shadow on them. With Local Light Transmittance on (URP Lighting only), transparent casters cast colored, partial point and spot light shadows on receivers using Sharp Stencil Shadows/Lit.

It costs nothing when no transparent caster is in a shadowed light's reach. Otherwise it adds one screen-sized RGBA8 target and texture array slice per such light, about 16 MB per light at 1080p.

StencilShadowRendererFeature.FindActive()?.SetUrpLightingLocalLightTransmittance(true);

The Sharp Stencil Shadows/Lit shader

Needed for colored and partial point and spot light shadows, and gives exact colored sun shadows. Switch receiver materials from Universal Render Pipeline/Lit to Sharp Stencil Shadows/Lit. Their settings carry over. See Receivers and Materials.

Limitations

  • Atlas shadows are only as detailed as their atlas tiles, and detail smaller than a texel is lost. See Caster Atlas.
  • An off-screen skinned atlas caster keeps its last visible pose unless Update When Offscreen is on.
  • A receiver between two layers of the same transparent caster is filtered by both.
  • Transparent casters don't receive shadows.
  • Alpha-clipped holes in point and spot light shadows need Textured mode.
  • Receivers using per-vertex additional lights get no transparent-caster shadows from point and spot lights.