the symptom, in your words

"DirectionalLight.LightColor is a hue control, not a brightness dial"

✓ verified on 26.07.22
lane Getting art inposted

▸ SYMPTOM

  • You build a day/night cycle that scales DirectionalLight.LightColor up and down to brighten and dim the sun, and nothing changes — noon and dusk render identically.
  • Multiplying the light's color by a small factor to "fade to night" has no visible effect, at any factor.
  • No error, no console warning — the ramp just does nothing.

▸ CAUSE

On this engine build, DirectionalLight.LightColor is a hue control, not an intensity/brightness dial. Multiplying the color by any positive scalar from 0.001 through 5.0 renders identically — there is no dimming range in between. The light is effectively on/off, not a continuous dial: only setting LightColor to exactly Color.Black turns it off.

Hand-writing the color's individual components changes nothing about this either — writing the component's fields directly produced no change, which points at engine-side normalization of the directional light color as the likely mechanism.

This corrects earlier notes that claimed DirectionalLight.LightColor "folds both hue and intensity — scale the color to dim/brighten." That was an editor-convention-level inference, never runtime-verified for DirectionalLight specifically, and live measurement shows the opposite.

▸ FIX

Do not build a brightness ramp on LightColor magnitude — it is a silent no-op.

  • Use LightColor for the sun's hue (warm noon, orange dusk), and set it to Color.Black only when you genuinely want the directional light off.
  • For the ambient/bounce side of a day/night cycle, DirectionalLight.SkyColor and SkyBox2D.Tint are real runtime-settable knobs — scale those for sky/ambient color shifts.
  • Treat directional brightness as an open problem. What actually controls perceived DirectionalLight brightness (tonemap/exposure, a separate multiplier, or something else) is unconfirmed on this build — do not assume LightColor scaling solves it.
snippet
var sun = go.Components.Get<DirectionalLight>();

// Hue works — this shifts the sun toward warm orange:
sun.LightColor = new Color( 1.0f, 0.7f, 0.4f );

// Brightness does NOT — every one of these renders the same:
sun.LightColor = baseColor * 0.1f;   // no change
sun.LightColor = baseColor * 2.0f;   // no change
sun.LightColor = Color.Black;        // the ONLY value that changes anything: off

▸ WHY IT WORKS

LightColor on the directional light appears to be normalized engine-side before it reaches the shader, so magnitude information in the color you set is discarded — only its hue survives, plus the degenerate "all-zero = off" case. That is why writing the raw components by hand is equally ineffective: the normalization happens downstream of your write. A brightness system has to reach a different knob (exposure/tonemap or a dedicated multiplier), which is still to be pinned down on this build.

Verified on engine 26.07.22: seen in a real project.
s&box moves fast; an undated fix is a liability. Spot a stale detail?
changelog
  • Published.

Want to know when new guides or fixes drop? Join the community to help build this out. Report gotchas, flag outdated fixes, or just lurk.

Join the Discord