Skip to main content
LightManager allows you to create light sources in the scene, such as a sun or street lights. At least one light must be added to a scene in order to see anything (unless Material.Shading.UNLIT is used).

Overview

Lights come in different types:
  • Directional lights - Parallel light rays from infinity (e.g., sun)
  • Point lights - Emit light from a position in all directions
  • Spot lights - Emit light from a position in a cone

Creation and Destruction

A Light component is created using the LightManager::Builder and destroyed by calling LightManager::destroy(utils::Entity).
filament::Engine* engine = filament::Engine::create();
utils::Entity sun = utils::EntityManager::get().create();

filament::LightManager::Builder(LightManager::Type::SUN)
    .castShadows(true)
    .build(*engine, sun);

engine->getLightManager().destroy(sun);

Light Types

Type::SUN
enum
Directional light that also draws a sun’s disk in the sky. All light rays are parallel and come from infinitely far away. Used to simulate the sun
Type::DIRECTIONAL
enum
Directional light that emits light in a given direction. Similar to SUN but without the sun disk visualization
Type::POINT
enum
Point light that emits light from a position in all directions. Intensity diminishes with inverse square of distance
Type::FOCUSED_SPOT
enum
Physically correct spot light. Changing the outer cone angle affects illumination levels
Type::SPOT
enum
Spot light with coupling of outer cone and illumination disabled. Allows independent control of cone angle and brightness

Builder Methods

Constructor

Creates a light builder and sets the light’s Type.
type
Type
required
Type of Light object to create
LightManager::Builder builder(LightManager::Type::POINT);

lightChannel

Enables or disables a light channel. Light channel 0 is enabled by default.
channel
unsigned int
required
Light channel to enable or disable, between 0 and 7
enable
bool
default:"true"
Whether to enable or disable the light channel
return
Builder&
This Builder, for chaining calls
builder.lightChannel(1, true).lightChannel(2, false);

castShadows

Whether this Light casts shadows (disabled by default).
enable
bool
required
Enables or disables casting shadows from this Light
return
Builder&
This Builder, for chaining calls
builder.castShadows(true);
Only Type::DIRECTIONAL, Type::SUN, Type::SPOT, or Type::FOCUSED_SPOT lights can cast shadows.

shadowOptions

Sets the shadow-map options for this light.
options
ShadowOptions
required
Shadow configuration options
return
Builder&
This Builder, for chaining calls
LightManager::ShadowOptions options;
options.mapSize = 2048;
options.shadowCascades = 3;
builder.shadowOptions(options);

castLight

Whether this light casts light (enabled by default).
enable
bool
required
Enables or disables lighting from this Light
return
Builder&
This Builder, for chaining calls
// Create a light that only casts shadows but doesn't illuminate
builder.castLight(false).castShadows(true);

position

Sets the initial position of the light in world space.
position
math::float3
required
Light’s position in world space. Default is at the origin
return
Builder&
This Builder, for chaining calls
builder.position({0.0f, 5.0f, 0.0f});
The Light’s position is ignored for directional lights (Type::DIRECTIONAL or Type::SUN).

direction

Sets the initial direction of a light in world space.
direction
math::float3
required
Light’s direction in world space. Should be a unit vector. Default is
return
Builder&
This Builder, for chaining calls
builder.direction({0.0f, -1.0f, 0.0f}); // Pointing downward
The Light’s direction is ignored for Type::POINT lights.

color

Sets the initial color of a light.
color
LinearColor
required
Color of the light specified in the linear sRGB color-space. Default is white
return
Builder&
This Builder, for chaining calls
builder.color({1.0f, 0.9f, 0.8f}); // Warm white

intensity

Sets the initial intensity of a light.
intensity
float
required
For directional lights: illuminance in lux (lumen/m²). For point/spot lights: luminous power in lumen
return
Builder&
This Builder, for chaining calls
// Sun's illuminance is about 100,000 lux
LightManager::Builder(LightManager::Type::SUN)
    .intensity(100000.0f)
    .build(*engine, sunEntity);

// Point light with 800 lumens (typical LED bulb)
LightManager::Builder(LightManager::Type::POINT)
    .intensity(800.0f)
    .build(*engine, bulbEntity);

intensity (Watts)

Sets the initial intensity of a light in watts.
watts
float
required
Energy consumed by a lightbulb. Related to brightness by the efficiency parameter
efficiency
float
required
Efficiency as a decimal (not percentage). See efficiency constants below
return
Builder&
This Builder, for chaining calls
// 60W incandescent bulb
builder.intensity(60.0f, LightManager::EFFICIENCY_INCANDESCENT);

// 10W LED bulb
builder.intensity(10.0f, LightManager::EFFICIENCY_LED);

Efficiency Constants

Lightbulb TypeConstantEfficiency
IncandescentEFFICIENCY_INCANDESCENT2.2%
HalogenEFFICIENCY_HALOGEN7.0%
FluorescentEFFICIENCY_FLUORESCENT8.7%
LEDEFFICIENCY_LED11.7%

intensityCandela

Sets the initial intensity of a spot or point light in candela.
intensity
float
required
Luminous intensity in candela
return
Builder&
This Builder, for chaining calls
builder.intensityCandela(1000.0f);

falloff

Set the falloff distance for point lights and spot lights.
radius
float
required
Falloff distance in world units. Default is 1 meter
return
Builder&
This Builder, for chaining calls
builder.falloff(10.0f); // 10 meter radius of influence
The Light’s falloff is ignored for directional lights (Type::DIRECTIONAL or Type::SUN).
Performance is very sensitive to overlapping lights. Use the smallest possible falloff distance and try to minimize overlap between lights.

spotLightCone

Defines a spot light’s angular falloff attenuation.
inner
float
required
Inner cone angle in radians, between 0.00873 (0.5°) and outer
outer
float
required
Outer cone angle in radians, between 0.00873 (0.5°) and π/2
return
Builder&
This Builder, for chaining calls
// 30 degree inner cone, 45 degree outer cone
float innerAngle = 30.0f * (M_PI / 180.0f);
float outerAngle = 45.0f * (M_PI / 180.0f);
builder.spotLightCone(innerAngle, outerAngle);
The spot light cone is ignored for directional and point lights.

sunAngularRadius

Defines the angular radius of the sun, in degrees.
angularRadius
float
required
Sun’s radius in degrees, between 0.25° and 20.0°. Default is 0.545°
return
Builder&
This Builder, for chaining calls
// The Sun as seen from Earth: 0.526° to 0.545°
builder.sunAngularRadius(0.545f);

sunHaloSize

Defines the halo radius of the sun.
haloSize
float
required
Radius multiplier of the sun angular radius. Default is 10.0
return
Builder&
This Builder, for chaining calls
builder.sunHaloSize(10.0f);

sunHaloFalloff

Defines the halo falloff of the sun.
haloFalloff
float
required
Dimensionless number used as an exponent. Default is 80.0
return
Builder&
This Builder, for chaining calls
builder.sunHaloFalloff(80.0f);

build

Adds the Light component to an entity.
engine
Engine&
required
Reference to the filament::Engine to associate this light with
entity
utils::Entity
required
Entity to add the light component to
return
Result
Success if the component was created successfully, Error otherwise
utils::Entity lightEntity = utils::EntityManager::get().create();
auto result = builder.build(*engine, lightEntity);
if (result == LightManager::Builder::Result::Success) {
    // Light created successfully
}
Currently, only 2048 lights can be created on a given Engine. If this component already exists on the entity, it is first destroyed.

ShadowOptions

Control the quality and performance of the shadow map associated with a light.
mapSize
uint32_t
default:"1024"
Size of the shadow map in texels. Must be a power-of-two and >= 8
shadowCascades
uint8_t
default:"1"
Number of shadow cascades (1-4). Only applicable to Type::SUN or Type::DIRECTIONAL lights. Values > 1 enable cascaded shadow mapping (CSM)
cascadeSplitPositions
float[3]
default:"{0.125, 0.25, 0.50}"
Split positions for shadow cascades. Values represent camera frustum split planes from near (0.0) to far (1.0)
constantBias
float
default:"0.001"
Constant bias in world units (e.g., meters). Default is 1mm. Ignored when View’s ShadowType is VSM
normalBias
float
default:"1.0"
Scale factor for maximum sampling error. Should be 1.0. Ignored when View’s ShadowType is VSM
shadowFar
float
default:"0.0"
Distance from camera after which shadows are clipped. Use 0.0 for camera far distance. Only affects directional lights
shadowNearHint
float
default:"1.0"
Optimize shadow quality from this distance (meters). Default 1m works well for many scenes
shadowFarHint
float
default:"100.0"
Optimize shadow quality in front of this distance (meters)
stable
bool
default:"false"
When true, optimizes for stability over resolution. Disables LiSPSM and resolution enhancements
lispsm
bool
default:"true"
Enable Light-space Perspective Shadow Mapping for better shadow resolution
polygonOffsetConstant
float
default:"0.5"
Constant depth bias in depth-resolution units. Generally should be small and positive
polygonOffsetSlope
float
default:"2.0"
Slope-based depth bias. Default works well with PCF_LOW. Essential for LiSPSM
screenSpaceContactShadows
bool
default:"false"
Whether to use screen-space contact shadows
stepCount
uint8_t
default:"8"
Number of ray-marching steps for screen-space contact shadows
maxShadowDistance
float
default:"0.3"
Maximum shadow-occluder distance for screen-space contact shadows (world units)
shadowBulbRadius
float
default:"0.02"
Light bulb radius for soft shadows (2cm default). Used with DPCF or PCSS
transform
math::quatf
default:"{1.0, 0, 0, 0}"
Transforms the shadow direction. Must be a unit quaternion. Ignored for non-directional lights
LightManager::ShadowOptions options;
options.mapSize = 2048;
options.shadowCascades = 4;
options.constantBias = 0.001f;
options.screenSpaceContactShadows = true;

LightManager::ShadowCascades::computeUniformSplits(
    options.cascadeSplitPositions, 4
);

builder.shadowOptions(options);

ShadowCascades Utilities

computeUniformSplits

Compute cascadeSplitPositions according to a uniform split scheme.
splitPositions
float*
required
Float array of at least size (cascades - 1) to write split positions into
cascades
uint8_t
required
Number of shadow cascades, at most 4
float splits[3];
LightManager::ShadowCascades::computeUniformSplits(splits, 4);

computeLogSplits

Compute cascadeSplitPositions according to a logarithmic split scheme.
splitPositions
float*
required
Float array of at least size (cascades - 1)
cascades
uint8_t
required
Number of shadow cascades, at most 4
near
float
required
Camera near plane distance
far
float
required
Camera far plane distance
float splits[3];
LightManager::ShadowCascades::computeLogSplits(splits, 4, 0.1f, 100.0f);

computePracticalSplits

Compute cascadeSplitPositions according to a practical split scheme.
splitPositions
float*
required
Float array of at least size (cascades - 1)
cascades
uint8_t
required
Number of shadow cascades, at most 4
near
float
required
Camera near plane distance
far
float
required
Camera far plane distance
lambda
float
required
Value in [0, 1] that interpolates between log and uniform split schemes. Start with 0.5
float splits[3];
LightManager::ShadowCascades::computePracticalSplits(splits, 4, 0.1f, 100.0f, 0.5f);

Instance Methods

getType

Returns the type of the light.
i
Instance
required
Instance of the component obtained from getInstance()
return
Type
The light type

isDirectional

Helper function that returns if a light is a directional light.
i
Instance
required
Instance of the component
return
bool
True if this light is Type::DIRECTIONAL or Type::SUN

isPointLight

Helper function that returns if a light is a point light.
i
Instance
required
Instance of the component
return
bool
True if this light is Type::POINT

isSpotLight

Helper function that returns if a light is a spot light.
i
Instance
required
Instance of the component
return
bool
True if this light is Type::SPOT or Type::FOCUSED_SPOT

setPosition

Dynamically updates the light’s position.
i
Instance
required
Instance of the component
position
math::float3
required
Light’s position in world space
auto instance = lightManager.getInstance(lightEntity);
lightManager.setPosition(instance, {0.0f, 10.0f, 0.0f});

getPosition

Returns the light’s position in world space.
i
Instance
required
Instance of the component
return
math::float3
Light position

setDirection

Dynamically updates the light’s direction.
i
Instance
required
Instance of the component
direction
math::float3
required
Light’s direction in world space. Should be a unit vector
lightManager.setDirection(instance, {0.0f, -1.0f, 0.0f});

getDirection

Returns the light’s direction in world space.
i
Instance
required
Instance of the component
return
math::float3
Light direction

setColor

Dynamically updates the light’s hue as linear sRGB.
i
Instance
required
Instance of the component
color
LinearColor
required
Color of the light in linear sRGB color-space
lightManager.setColor(instance, {1.0f, 0.9f, 0.8f});

getColor

Returns the light’s color in linear sRGB.
i
Instance
required
Instance of the component
return
math::float3
Light color

setIntensity

Dynamically updates the light’s intensity. The intensity can be negative.
i
Instance
required
Instance of the component
intensity
float
required
For directional lights: illuminance in lux. For point/spot lights: luminous power in lumen
lightManager.setIntensity(instance, 50000.0f);

getIntensity

Returns the light’s luminous intensity in candela.
i
Instance
required
Instance of the component
return
float
Luminous intensity in candela. For Type::FOCUSED_SPOT lights, depends on outer cone angle

setShadowCaster

Enables or disables shadow casting for this light.
i
Instance
required
Instance of the component
shadowCaster
bool
required
Enables or disables casting shadows
lightManager.setShadowCaster(instance, true);

isShadowCaster

Returns whether this light casts shadows.
i
Instance
required
Instance of the component
return
bool
True if shadow casting is enabled

Complete Example

#include <filament/Engine.h>
#include <filament/LightManager.h>
#include <utils/EntityManager.h>

using namespace filament;
using namespace utils;

// Create engine and entity
Engine* engine = Engine::create();
Entity sunEntity = EntityManager::get().create();

// Configure shadow options
LightManager::ShadowOptions shadowOptions;
shadowOptions.mapSize = 2048;
shadowOptions.shadowCascades = 3;
LightManager::ShadowCascades::computePracticalSplits(
    shadowOptions.cascadeSplitPositions, 3, 0.1f, 100.0f, 0.5f
);

// Create a sun light
LightManager::Builder(LightManager::Type::SUN)
    .color({1.0f, 0.95f, 0.9f})
    .intensity(100000.0f)  // 100,000 lux
    .direction({0.3f, -1.0f, -0.3f})
    .sunAngularRadius(0.545f)
    .castShadows(true)
    .shadowOptions(shadowOptions)
    .build(*engine, sunEntity);

// Create a point light (street lamp)
Entity lampEntity = EntityManager::get().create();
LightManager::Builder(LightManager::Type::POINT)
    .color({1.0f, 0.9f, 0.7f})
    .intensity(800.0f)  // 800 lumens
    .position({5.0f, 3.0f, 0.0f})
    .falloff(10.0f)  // 10 meter radius
    .build(*engine, lampEntity);

// Create a spot light
Entity spotEntity = EntityManager::get().create();
float innerAngle = 20.0f * (M_PI / 180.0f);
float outerAngle = 30.0f * (M_PI / 180.0f);

LightManager::Builder(LightManager::Type::SPOT)
    .color({1.0f, 1.0f, 1.0f})
    .intensity(1000.0f)
    .position({0.0f, 5.0f, 0.0f})
    .direction({0.0f, -1.0f, 0.0f})
    .falloff(15.0f)
    .spotLightCone(innerAngle, outerAngle)
    .build(*engine, spotEntity);

Performance Tips

  1. Prefer spot lights to point lights and use the smallest outer cone angle possible
  2. Use the smallest possible falloff distance for point and spot lights
  3. Minimize overlapping lights - Performance is very sensitive to light overlap
  4. Hundreds of non-overlapping lights can be handled without significant overhead
  5. Only one directional light is currently supported - if multiple are added, the dominant one will be used

Build docs developers (and LLMs) love