Describe the bug
Calling LightManager$Builder.shadowOptions(...) or LightManager.setShadowOptions(...) from Filament.js fails at runtime with an Embind “unbound types” error. The API is present in filament.d.ts and in the JavaScript wrapper, but the runtime cannot bind LightManager$ShadowOptions.
This prevents setting shadow parameters such as mapSize, shadowCascades, shadowNearHint, and shadowFarHint from JavaScript.
To Reproduce
Steps to reproduce the behavior:
- Load Filament.js in a WebGL application.
- Create a
SUN light.
- Call
shadowOptions on the builder:
Filament.LightManager.Builder(Filament.LightManager$Type.SUN)
.color([1.0, 0.95, 0.88])
.intensity(95000.0)
.direction([0.55, -0.75, -0.35])
.castShadows(true)
.shadowOptions({
mapSize: 4096,
shadowCascades: 3,
shadowNearHint: 0.5,
shadowFarHint: 10.0,
})
.build(engine, sunlight);
- Alternatively, build the light first and call:
const lcm = engine.getLightManager();
const instance = lcm.getInstance(sunlight);
lcm.setShadowOptions(instance, {
mapSize: 4096,
shadowCascades: 3,
shadowNearHint: 0.5,
shadowFarHint: 10.0,
});
- Observe the runtime error.
Expected behavior
shadowOptions(...) and setShadowOptions(...) should accept a JavaScript object matching the documented LightManager$ShadowOptions interface and apply the requested shadow settings.
For example, changing mapSize should visibly affect shadow-map resolution.
Screenshots
Not applicable. The relevant information is in the console logs below.
Logs
Error: Cannot call LightManager$Builder._shadowOptions due to unbound types: 0xc1efa
at throwUnboundTypeError (filament.js:1:74262)
at unboundTypesHandler (filament.js:1:83235)
at Filament.LightManager$Builder.shadowOptions (filament.js:771)
at createLights (main.js:448)
at new App (main.js:149)
When using LightManager.setShadowOptions(...) instead:
Error: Cannot call LightManager._setShadowOptions due to unbound types: 0xc1efa
at throwUnboundTypeError (filament.js:1:74262)
at unboundTypesHandler (filament.js:1:83235)
at Filament.LightManager.setShadowOptions (filament.js:657)
at createLights (main.js:463)
at new App (main.js:149)
Additional console output:
FEngine (32 bits) created
[WebKit], [WebKit WebGL], [OpenGL ES 3.0 (WebGL 2.0)], [OpenGL ES GLSL ES 3.00 (WebGL GLSL ES 3.00)]
Feature level: 1
Backend feature level: 1
FEngine feature level: 1
Desktop (please complete the following information):
- OS: macOS 26 / Darwin 25.3.0
- GPU: [please fill in GPU model]
- Backend: WebGL 2.0 / OpenGL ES 3.0
Smartphone (please complete the following information):
- Device: Not applicable
- OS: Not applicable
Additional context
The TypeScript declaration exposes the API:
export interface LightManager$ShadowOptions {
mapSize?: number;
shadowCascades?: number;
constantBias?: number;
normalBias?: number;
shadowFar?: number;
shadowNearHint?: number;
shadowFarHint?: number;
stable?: boolean;
polygonOffsetConstant?: number;
polygonOffsetSlope?: number;
screenSpaceContactShadows?: boolean;
stepCount?: number;
maxShadowDistance?: number;
}
However, the generated JavaScript runtime appears to route both APIs through native bindings:
Filament.LightManager.prototype.setShadowOptions = function(instance, overrides) {
this._setShadowOptions(instance, Filament.shadowOptions(overrides));
};
Filament.LightManager$Builder.prototype.shadowOptions = function(overrides) {
return this._shadowOptions(Filament.shadowOptions(overrides));
};
The upstream native binding appears to include additional fields in LightManager::ShadowOptions, including fields not present in the .d.ts, such as lispsm, shadowBulbRadius, and transform. The transform field may be relevant because it is a native matrix type and may not be bound correctly for JavaScript object conversion.
The local application can render correctly when no shadow options are set. The failure occurs specifically when attempting to pass LightManager$ShadowOptions through either the builder or manager API.
Describe the bug
Calling
LightManager$Builder.shadowOptions(...)orLightManager.setShadowOptions(...)from Filament.js fails at runtime with an Embind “unbound types” error. The API is present infilament.d.tsand in the JavaScript wrapper, but the runtime cannot bindLightManager$ShadowOptions.This prevents setting shadow parameters such as
mapSize,shadowCascades,shadowNearHint, andshadowFarHintfrom JavaScript.To Reproduce
Steps to reproduce the behavior:
SUNlight.shadowOptionson the builder:Expected behavior
shadowOptions(...)andsetShadowOptions(...)should accept a JavaScript object matching the documentedLightManager$ShadowOptionsinterface and apply the requested shadow settings.For example, changing
mapSizeshould visibly affect shadow-map resolution.Screenshots
Not applicable. The relevant information is in the console logs below.
Logs
When using
LightManager.setShadowOptions(...)instead:Error: Cannot call LightManager._setShadowOptions due to unbound types: 0xc1efa at throwUnboundTypeError (filament.js:1:74262) at unboundTypesHandler (filament.js:1:83235) at Filament.LightManager.setShadowOptions (filament.js:657) at createLights (main.js:463) at new App (main.js:149)Additional console output:
Desktop (please complete the following information):
Smartphone (please complete the following information):
Additional context
The TypeScript declaration exposes the API:
However, the generated JavaScript runtime appears to route both APIs through native bindings:
The upstream native binding appears to include additional fields in
LightManager::ShadowOptions, including fields not present in the.d.ts, such aslispsm,shadowBulbRadius, andtransform. Thetransformfield may be relevant because it is a native matrix type and may not be bound correctly for JavaScript object conversion.The local application can render correctly when no shadow options are set. The failure occurs specifically when attempting to pass
LightManager$ShadowOptionsthrough either the builder or manager API.