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:
committed by
Copybara-Service
parent
92261d9095
commit
f9a00bd5b5
@@ -2644,6 +2644,14 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
||||
doc='OpenGL cutoff',
|
||||
array_extent=('nlight',),
|
||||
),
|
||||
StructFieldDecl(
|
||||
name='light_softness',
|
||||
type=PointerType(
|
||||
inner_type=ValueType(name='float'),
|
||||
),
|
||||
doc='spotlight edge softness',
|
||||
array_extent=('nlight',),
|
||||
),
|
||||
StructFieldDecl(
|
||||
name='light_exponent',
|
||||
type=PointerType(
|
||||
@@ -8411,6 +8419,11 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
||||
type=ValueType(name='float'),
|
||||
doc='OpenGL cutoff',
|
||||
),
|
||||
StructFieldDecl(
|
||||
name='softness',
|
||||
type=ValueType(name='float'),
|
||||
doc='spotlight edge softness',
|
||||
),
|
||||
StructFieldDecl(
|
||||
name='exponent',
|
||||
type=ValueType(name='float'),
|
||||
@@ -10633,6 +10646,11 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
||||
type=ValueType(name='float'),
|
||||
doc='range of effectiveness',
|
||||
),
|
||||
StructFieldDecl(
|
||||
name='softness',
|
||||
type=ValueType(name='float'),
|
||||
doc='spotlight edge softness',
|
||||
),
|
||||
),
|
||||
)),
|
||||
('mjvOption',
|
||||
|
||||
@@ -1259,6 +1259,7 @@ This is useful for example when the MJB is not available as a file on disk.)"));
|
||||
X(bulbradius);
|
||||
X(intensity);
|
||||
X(range);
|
||||
X(softness);
|
||||
#undef X
|
||||
|
||||
#define X(var) DefinePyArray(mjvLight, #var, &MjvLightWrapper::var)
|
||||
|
||||
Reference in New Issue
Block a user