Add light softness: spotlight edge softness for physically-based rendering.

The new spotlight attribute softness (real in [0, 1], default 0) is the
fraction of the cone, measured inward from the cutoff, over which
intensity falls to zero. It is used by physically-based lighting models;
the Phong model's corresponding knob remains exponent.

The filament renderer previously hardcoded the inner cone angle to 0,
making the entire beam penumbra: the shader attenuates by the squared
smoothstep ((cos(theta) - cos(outer)) / (cos(inner) - cos(outer)))^2, so
a cutoff-25 spot delivered its rated candela only exactly on-axis and
about a third of it averaged over the light pool, with the deficit
shrinking as the cutoff widens. The inner angle is now
(1 - softness) * cutoff, so at the default the light delivers its full
intensity everywhere inside the cone and illuminance follows E = I/d^2
independent of the cutoff. Setting softness to 1 reproduces the previous
appearance exactly (verified bit-identical), which is the migration path
for models tuned against the old behavior.

The filament light type also changes from FOCUSED_SPOT to SPOT. With
intensity given in candela and the cone set at build time the two types
produce identical output (FOCUSED_SPOT's power-conserving rescale only
applies when the cone changes after the intensity is set), but SPOT
guarantees that candela never rescales with cone angle should the cone
ever become runtime-editable.

Verified with headless renders under a linear tone mapper against an
equal-candela point light at cutoffs 25/45/80: softness 0 gives
spot/point luminance ratio 1.000 at all sampled angles inside the cone;
softness 0.2 is flat over the inner 80% of the cone; softness 1 matches
the previous renderer with zero linear-pixel difference. XML round-trip
and the [0, 1] compile-time check verified. Introspect and wasm bindings
regenerated.

PiperOrigin-RevId: 959334706
Change-Id: I0f0729781899880de1729ea9b3d8c055d715a025
This commit is contained in:
Yuval Tassa
2026-08-04 18:11:03 -07:00
committed by Copybara-Service
parent 92261d9095
commit f9a00bd5b5
27 changed files with 118 additions and 15 deletions
+18 -4
View File
@@ -3307,18 +3307,30 @@ Attributes may be applied or ignored depending on the lighting model being used.
.. _body-light-attenuation:
:at:`attenuation`: :at-val:`real(3), "1 0 0"`
These are the constant, linear and quadratic attenuation coefficients for Phong lighting.
The default corresponds to no attenuation.
These are the constant, linear and quadratic attenuation coefficients, used by the default Phong lighting model.
The default corresponds to no attenuation. Physically-based lighting models instead attenuate with the inverse
square of distance, scaled by :ref:`intensity<body-light-intensity>` and limited by :ref:`range<body-light-range>`.
.. _body-light-cutoff:
:at:`cutoff`: :at-val:`real, "45"`
Cutoff angle for spotlights, always in degrees regardless of the global angle setting.
Cutoff angle for spotlights, always in degrees regardless of the global angle setting. The falloff of intensity
inside the cone is controlled by :ref:`softness<body-light-softness>` for physically-based lighting models and by
:ref:`exponent<body-light-exponent>` for the default Phong lighting model.
.. _body-light-softness:
:at:`softness`: :at-val:`real, "0"`
Edge softness for spotlights, as a fraction of the :ref:`cutoff<body-light-cutoff>` angle in [0, 1], used by
physically-based lighting models. The light delivers its full :ref:`intensity<body-light-intensity>` inside the
cone, falling to zero over the outer softness fraction of the cone angle; the default corresponds to a sharp-edged
cone. This is unused by the default Phong lighting model, which uses :ref:`exponent<body-light-exponent>`.
.. _body-light-exponent:
:at:`exponent`: :at-val:`real, "10"`
Exponent for spotlights. This setting controls the softness of the spotlight cutoff.
Exponent for spotlights, used by the default Phong lighting model. This setting controls the softness of the
spotlight cutoff. Physically-based lighting models use :ref:`softness<body-light-softness>` instead.
.. _body-composite:
@@ -10035,6 +10047,8 @@ if omitted.
.. _default-light-cutoff:
.. _default-light-softness:
.. _default-light-exponent:
.. _default-light-mode: