compute_shadow_map

compute_shadow_map

English | 日本語

compute_shadow_map

Overview

This sample verifies one directional-light shadow map. webg/ShadowMapPass.js renders the scene from the light into a depth texture, while GeometryBufferPass produces camera-space albedo, normals, and depth. webg/ComputeShadowPass.js reconstructs camera positions in world space, projects them into light space, and compares them with the shadow map.

Shadow-map generation stays in a Render Pass, while shadow evaluation and composition use a Compute Pass. Triangle rasterization and depth testing remain in the Render Pipeline, and the Compute Shader focuses on bias, PCF, and debug views. This follows the same responsibility split used by the current webg 2 flow, where GeometryBufferPass produces inputs and passes such as SsaoPass or DeferredLightingPass consume them.

ShadowMapPass is now a webg core implementation. It collects static and skinned Shapes from Space and renders them with a depth-only Render Pass. For skinned Shapes, it reads the standard Shape's two vertex buffers and the Skeleton matrix palette, so the shadow map uses the same bone pose as normal rendering and GeometryBufferPass. Alpha testing is still unsupported and is not silently replaced with another path.

FrameTimer measures the shadow-depth and G-buffer Render Passes plus the shadow-evaluation Compute Pass with timestamp queries. The CommandPalette and Help panel display GPU Compute, GPU Render, GPU Total, and GPU Load. GPU Load is the measured total GPU time divided by the frame interval. The final fullscreen copy is outside the measured range.

Processing Flow

Space
  -> ShadowMapPass
  -> directional light depth

Space
  -> GeometryBufferPass
  -> camera albedo / normal / depth

camera G-buffer + light depth
  -> ComputeShadowPass
  -> shadowed color
  -> FullscreenPass
  -> canvas

The directional light uses an orthographic projection. Its view-projection matrix comes from the light direction, target center, light distance, orthographic extent, near plane, and far plane. When a shadow is clipped, first check whether the scene fits inside the orthographic extent.

Spot-light shadows are handled by the core SpotShadowMapPass and ComputeSpotShadowPass. A spot light builds a perspective light view-projection matrix from its position, direction, FOV, inner / outer angles, near plane, and far plane, then fades lighting outside the cone. This sample focuses on the low-level directional-light setup, so spot-light shadow verification belongs to applications that use ComputeEffectPipeline with shadow.type: "spot".

How to Run

Controls and Checkpoints

The shadow view displays visibility as white and occlusion as black. Fine self-shadowing patterns usually indicate insufficient bias, while a detached shadow suggests excessive bias. PCF radius 0 uses one sample, radius 1 uses 3×3 samples, and radius 2 uses 5×5 samples.

The green cylinder near the camera is closed with flat caps at both ends, bends continuously with five bones, and also moves and rotates as a Node. Cap vertices are separate from the side vertices and fixed to the corresponding end bone, so the caps do not separate while bending. Its movement, rotation, bending, and shadow silhouette on the floor must change together. ShadowMapPass reuses one bone-palette Buffer and Bind Group per Skeleton and updates only the current matrix palette each frame. Static Shapes use the same pipeline with an explicit skinning-disabled flag and a formal dummy vertex binding, so bone transforms cannot be applied accidentally.

This version covers static and skinned opaque Shapes, one directional light, and a fixed 1024×1024 shadow map. Spot-light support is available as a core API, but this sample does not exercise it. Cascaded Shadow Maps, point lights, alpha testing, and automatic light-frustum fitting remain future work.