Render the Environment light's shadow from its image (#2436)

The Casts Shadows option Environment lights got is only half a fix if
nothing shades for it: an image lights the scene from every direction,
and what occludes that light is the image itself — its dominant bright
region, the sun in a sky map.

- dominant_direction finds it: the radiance-weighted mean texel
  direction (solid-angle weighted, rotation applied). A uniform image
  cancels to zero — a flat default environment shines from everywhere
  at once and casts no shadow, which a uniform environment test pins.
- The shadow is one orthographic map over the scene from that
  direction, after the lights' maps, like a parallel light's: PCF
  widened by Shadow Diffusion, darkened by Shadow Darkness, cleared
  when nothing casts, the image is directionless, or the texel budget
  drops it.
- It darkens the environment's own diffuse and specular light on
  Accepts Shadows surfaces and counts in Cast Shadows Only. CPU and
  GPU (WGSL) do the same; Globals carries the environment's sun
  direction and shadow settings (40 → 44 floats, preflight updated).

A bright-disc environment turned to shine from behind the camera now
shadows a sphere onto the floor behind it, Cast Shadows off lights it
evenly again, and the GPU scene's sky gradient takes a shadow-casting
Environment light. Also: the renderer-switch toasts read "...renderer,
which draws 3D models", the dialog's Casts Shadows checkbox gets an
auto id (dialog.light.casts) the tests click, and the docs' Environment
notes cover the shadow.
This commit is contained in:
Minher0
2026-10-26 13:05:16 +00:00
parent 1599790ac9
commit 863f0e49c1
15 changed files with 384 additions and 87 deletions
+5 -3
View File
@@ -214,9 +214,11 @@ Things that tripped up a long agent-driven session (a multi-scene 3D piece built
image that metallic surfaces reflect. Set its `lightOptions/source` to a footage, comp or solid
layer by layer id; with no source it uses the comp's Environment Layer (`layer.environment`),
or a flat default environment of the light's colour × intensity when there is none — either
way the light brightens the scene, and it has `castsShadows`/`shadowDarkness`/`shadowDiffusion`
like the other lights. It only lights Advanced 3D comps, so creating one (or changing a light's
type to Environment) switches a Classic 3D comp to Advanced 3D
way the light brightens the scene. It has `castsShadows`/`shadowDarkness`/`shadowDiffusion`
like the other lights: Cast Shadows shades the scene from the image's dominant bright region
(a flat or otherwise uniform environment has none, so it casts no shadow). It only lights
Advanced 3D comps, so creating one (or changing a light's type to Environment) switches a
Classic 3D comp to Advanced 3D
([#261](https://github.com/storytold/effectcraft/issues/261),
[#2436](https://github.com/storytold/effectcraft/issues/2436)).
+5 -3
View File
@@ -161,9 +161,11 @@ light from an Environment light whose Source (or the comp's Environment Layer, L
Environment Layer, or a flat default environment of the light's colour × intensity when
there is neither) is an equirectangular image (cosine irradiance map; roughness-indexed mip
chain with the split-sum environment BRDF fit), and percentage-closer-filtered shadow maps
(spot: perspective, parallel: orthographic over the scene, point: six cube faces). An
Environment light only lights Advanced 3D comps, so adding one (or changing a light's type to
it) switches a Classic 3D comp to Advanced 3D, as model layers do. Cards keep
(spot: perspective, parallel: orthographic over the scene, point: six cube faces, environment:
one orthographic from the image's dominant bright region — none when the image is
directionless, as a flat environment is). An Environment light only lights Advanced 3D comps,
so adding one (or changing a light's type to it) switches a Classic 3D comp to Advanced 3D,
as model layers do. Cards keep
Material Options (Accepts Lights/Shadows, Casts Shadows On/Only, Ambient, Diffuse, Specular);
models and primitives add Base Color, Metallic, Roughness, Emissive. Rasterisation runs at 2×2
supersampling with a reversed-Z depth buffer; opaque triangles resolve visibility first, the