Skip to content

Shadows

EntropyPortal implements a Virtual Shadow Map (VSM) system that supports high-resolution shadows for multiple light types.

Traditional shadow mapping requires allocating a texture for every shadow-casting light, which consumes immense VRAM. VSM solves this by allocating a single, large Shadow Atlas (e.g., 8192x8192) and virtualizing the pages.

  • Shadow Atlas: A massive texture array where all active shadow pages reside.
  • Page Table: A structure mapping (LightID, Face, lod) to a physical page in the atlas.
  • Sparse Allocation: Only pages that are visible on screen are allocated and updated.
  • Uses Cascaded Shadow Maps (CSM) to handle large outdoor scenes.
  • Typically 4 cascades per directional light.
  • Splits are calculated logarithmically (cascadeLambda) to balance near-field resolution and far-field coverage.
  • Rendered as 6-face cubemaps into the atlas.
  • Used for local light sources.
  • Rendered as a single perspective projection.
  • Most efficient shadow type.

The VirtualShadowMapService manages the atlas and page tables.

graph TD
    Start([Frame Start]) --> Collect[Collect Lights]
    Collect --> Layout["Atlas Layout<br/>(Shelf Packing)"]
    Layout --> Matrices[Compute Matrices]
    Matrices --> Render[Render Shadow Passes]
    Render --> Upload["Upload Metadata<br/>(Page Tables)"]
    Upload --> End([Frame End])
  1. Culling: Determine which lights cast shadows on visible geometry.
  2. Allocation: Allocate pages in the atlas for required shadow faces.
  3. Rendering: Render depth for all allocated pages in a single pass (or batched passes).
  4. Sampling: In the shader, the ShadowAtlas is sampled using manual PCF or hardware comparison samplers.