Shadow State
Per-frame state for the directional sun-shadow pipeline. Owned by ShadowLayer, populated during render, and consumed by earth.worldwind.draw.DrawableShadow (depth pass) and by receiver shaders (terrain, lit shapes, 3D-Tile meshes) during the main pass.
The pipeline uses Cascaded Shadow Maps: the camera frustum's scene-fit depth range is sliced into cascadeCount sub-ranges and each slice gets its own light-space orthographic projection sized to that slice's world-space footprint. The depth pass renders casters into one depth texture per cascade; receivers select a cascade per-fragment from view-space depth and resolve occlusion with a bilinear-weighted percentage-closer filter.
Receiver-side shadow math runs in camera-relative coordinates: CascadeState.shadowMatrix maps worldPos - cameraPoint into the cascade's [0, 1]^3 texture space. Composing the camera translation into the matrix on the CPU (in double precision) keeps fragment-shader inputs at view-distance magnitude — a raw ECEF world position quantizes to ~0.5 m in float32, which would erase street-scale shadow detail entirely.
Types
Per-cascade light-space transforms and view-frustum slice metadata.
Properties
Multiplier for shadowed-fragment colour on UNLIT receivers (terrain imagery, photogrammetry, points), where the shadow term is the only sun shading. 0.0 => fully black shadow, 1.0 => no darkening; the default 0.4 is a perceptual mid-point that reads as a directional shadow without obscuring the underlying albedo. Lit receivers ignore it - their shadow floor is the scene ambient term (see earth.worldwind.render.program.LightingGlsl).
Camera position the cascade CascadeState.shadowMatrix matrices are relative to.
Number of cascades. Default 4 spans street-scale detail to globe-scale coverage.
One CascadeState per slice; index 0 is the closest cascade.
Debug visualisation mode: 0 off, 1 cascade bands (1.0 / 0.75 / 0.5 / 0.25 per cascade), 2 footprint coverage, 3 raw shadow-map depth projected onto the scene.
Monotonic counter incremented every frame that ShadowLayer.doRender populates new cascades. Drives the per-frame caching in applyShadowReceiverUniforms: cascade texture binds and per-program uniform uploads are skipped when this stamp hasn't changed since the last call.
true when the cascade depth maps are populated and receivers may sample them. Set by ShadowLayer at render time; cleared by earth.worldwind.draw.DrawableShadow at draw time when the GL implementation can't run the pipeline (no sized formats / depth textures).
Snapshot of ShadowLayer.isTerrainCastingEnabled — gates terrain in the depth pass.
World-space unit vector toward the sun, snapshotted from earth.worldwind.render.RenderContext.lightDirection. Receivers use it for the normal-offset and normal-shading terms.
Snapshot of ShadowLayer.offscreenCasterCascades, clamped to cascadeCount. Consumed by earth.worldwind.render.RenderContext.intersectsShadowCasterRegion.
Effective far cap of the last cascade in metres for this frame. Receivers fade shadows out over the last 20% of this distance so the far cascade edge never pops.
Effective Lambertian terrain shading strength for this frame (ShadowLayer.terrainLambert scaled by the terminator fade). Consumed by earth.worldwind.render.program.SurfaceTextureProgram; 0 keeps unshaded imagery.
Functions
Deep-copy source into this instance. Lets ShadowLayer publish per-frame cascades into a earth.worldwind.frame.Frame-owned ShadowState without leaking a reference to its scratch state.