Skip to content

Shadows

Shadows add depth and realism. Plinken provides both global shadow settings and per-light shadow controls (see Lights).

Access via scene.shadows:

local shadows = scene.shadows
shadows.enabled = true -- global toggle, default false
shadows.resolution = 2048 -- shadow map resolution, default 2048

Directional lights use cascaded shadow maps (CSM) for high-quality shadows across large distances. Close objects get higher resolution.

shadows.cascade_count = 4 -- 1–4 cascades, default 4
shadows.cascade_split = { 0.1, 0.3, 0.6 } -- split boundaries (normalized)

The split array defines where each cascade boundary falls between the camera’s near and far planes. Fewer cascades = better performance; more cascades = better quality at distance.

Bias settings prevent shadow acne (self-shadowing artifacts) and peter-panning (shadows detaching from objects):

shadows.depth_bias = 0.005 -- push shadow away from light, default 0.005
shadows.normal_bias = 0.02 -- push along surface normal, default 0.02
  • Too low: shadow acne (Moiré patterns on lit surfaces)
  • Too high: peter-panning (shadows float away from objects)

Soft shadows blur the shadow edges for a more realistic look:

shadows.soft = true -- enable PCF filtering, default false
shadows.pcf_samples = 16 -- number of filter samples, default 16

Higher sample counts produce smoother edges but cost more performance.

Soft shadows are currently stubbed — values are stored but not rendered yet.

Individual lights can override shadow behavior:

local light = scene:create_light("Key", "directional")
light.cast_shadow = true -- default false
light.shadow_resolution = 1024 -- per-light override
light.shadow_bias = 0.005

See Lights for full per-light properties.

local shadows = scene.shadows
-- Enable with high resolution
shadows.enabled = true
shadows.resolution = 4096
-- 4 cascades for smooth coverage
shadows.cascade_count = 4
shadows.cascade_split = { 0.05, 0.15, 0.4 }
-- Balanced bias
shadows.depth_bias = 0.003
shadows.normal_bias = 0.015
-- Soft edges
shadows.soft = true
shadows.pcf_samples = 32
-- Make the key light cast shadows
local key = scene:create_light("Key", "directional")
key.direction = { x = -0.5, y = -1, z = -0.3 }
key.intensity = 8.0
key.cast_shadow = true
key.shadow_resolution = 2048