The Camera in Filament represents the viewpoint through which the scene is rendered. It controls projection (perspective or orthographic), exposure settings, and focus parameters.
Creating a Camera
Cameras are components associated with entities:
utils ::Entity cameraEntity = utils :: EntityManager :: get (). create ();
Camera * camera = engine -> createCamera (cameraEntity);
// Set projection
camera -> setProjection ( 45.0 , 16.0 / 9.0 , 0.1 , 100.0 );
// Set position and orientation
camera -> lookAt ({ 0 , 1.6 , 3 }, { 0 , 0 , 0 });
// Assign to view
view -> setCamera (camera);
Projection
Filament supports perspective and orthographic projection.
Perspective Projection
Simulates realistic perspective with objects getting smaller as they recede:
// Field of view method
camera -> setProjection (
45.0 , // FOV in degrees
16.0 / 9.0 , // Aspect ratio (width/height)
0.1 , // Near plane
100.0 , // Far plane
Camera :: Fov ::VERTICAL // FOV direction
);
// Focal length method
camera -> setLensProjection (
28.0 , // Focal length in millimeters
16.0 / 9.0 , // Aspect ratio
0.1 , // Near plane
100.0 // Far plane
);
FOV directions:
Camera::Fov::VERTICAL: FOV applies to vertical axis
Camera::Fov::HORIZONTAL: FOV applies to horizontal axis
Orthographic Projection
Parallel projection with no perspective distortion:
camera -> setProjection (
Camera :: Projection ::ORTHO,
- 10.0 , // Left
10.0 , // Right
- 10.0 , // Bottom
10.0 , // Top
0.1 , // Near
100.0 // Far
);
Custom Projection
Set a custom projection matrix:
math ::mat4 customProjection = ...;
camera -> setCustomProjection (
customProjection,
0.1 , // Near
100.0 // Far
);
// With separate culling matrix
math ::mat4 cullingProjection = ...;
camera -> setCustomProjection (
customProjection,
cullingProjection,
0.1 ,
100.0
);
Custom projection matrices must define an NDC system matching OpenGL conventions (all axes mapped to [-1, 1]).
Projection Utilities
// Get static projection matrix
math ::mat4 proj = Camera :: projection (
Camera :: Fov ::VERTICAL,
45.0 ,
16.0 / 9.0 ,
0.1 ,
100.0
);
// Get projection from focal length
math ::mat4 proj = Camera :: projection (
28.0 , // Focal length in mm
16.0 / 9.0 ,
0.1 ,
100.0
);
Near and Far Planes
Choosing Near Plane
The near plane distance critically affects depth buffer precision. Use the highest value possible:
// Poor precision
camera -> setProjection ( 45.0 , aspect, 0.001 , 1000.0 ); // Too small
// Good precision
camera -> setProjection ( 45.0 , aspect, 0.1 , 1000.0 ); // Better
camera -> setProjection ( 45.0 , aspect, 1.0 , 1000.0 ); // Best (if viable)
Depth precision at different near values (32-bit float depth):
Near (m) Precision at 1m Precision at 10m Precision at 100m 0.001 7.2e-5 0.0043 0.4624 0.01 6.9e-6 0.0001 0.0430 0.1 3.6e-7 7.0e-5 0.0072 1.0 0 3.8e-6 0.0007
Choosing Far Plane
The far plane is used for culling and shadowing. Keep a reasonable near:far ratio:
// Recommended ratios: 1:100 to 1:100,000
camera -> setProjection ( 45.0 , aspect, 0.1 , 100.0 ); // Ratio 1:1000
camera -> setProjection ( 45.0 , aspect, 1.0 , 1000.0 ); // Ratio 1:1000
The far plane is set to infinity for rendering to improve depth precision, but is used for culling. Large near:far ratios may cause rendering artifacts.
Setting Position and Orientation
// Look-at method (easiest)
camera -> lookAt (
{ 0 , 2 , 5 }, // Eye position
{ 0 , 0 , 0 }, // Look-at target
{ 0 , 1 , 0 } // Up vector (default: {0,1,0})
);
// Transform matrix method
math ::mat4 transform = math :: mat4 :: translation ({ 0 , 2 , 5 }) *
math :: mat4 :: rotation (angle, { 0 , 1 , 0 });
camera -> setModelMatrix (transform);
Getting Camera Properties
// World position
math ::double3 position = camera -> getPosition ();
// Direction vectors
math ::float3 forward = camera -> getForwardVector (); // -Z axis
math ::float3 up = camera -> getUpVector (); // +Y axis
math ::float3 left = camera -> getLeftVector (); // -X axis
// Matrices
math ::mat4 model = camera -> getModelMatrix (); // World transform
math ::mat4 view = camera -> getViewMatrix (); // Inverse of model
math ::mat4 proj = camera -> getProjectionMatrix (); // Projection (infinite far)
math ::mat4 culling = camera -> getCullingProjectionMatrix (); // With finite far
// Frustum
Frustum frustum = camera -> getFrustum (); // In world space
// Field of view
float fovDegrees = camera -> getFieldOfViewInDegrees ( Camera :: Fov ::VERTICAL);
Exposure
Camera exposure controls scene brightness using physically-based parameters.
Exposure from Camera Settings
// Default: f/16, 1/125s, 100 ISO (good for outdoor sunny day)
camera -> setExposure (
16.0 f , // Aperture (f-stop)
1.0 / 125.0 , // Shutter speed (seconds)
100.0 f // Sensitivity (ISO)
);
// Indoor scene
camera -> setExposure (
2.8 f , // Wide aperture (more light)
1.0 / 60.0 , // Slower shutter
400.0 f // Higher ISO
);
// Night scene
camera -> setExposure (
1.8 f , // Very wide aperture
1.0 / 30.0 , // Slow shutter
1600.0 f // High ISO
);
Parameter ranges:
Aperture : 0.5 to 64 (realistic: 0.95 to 32)
Lower = brighter (more light)
Common values: 1.4, 2.0, 2.8, 4.0, 5.6, 8.0, 11, 16, 22
Shutter speed : 1/25000 to 60 seconds (realistic: 1/8000 to 30)
Lower = brighter (more time for light)
Common values: 1/8000, 1/4000, 1/2000, 1/1000, 1/500, 1/250, 1/125, 1/60, 1/30
Sensitivity : 10 to 204,800 ISO (realistic: 50 to 25,600)
Higher = brighter (more sensitive)
Common values: 50, 100, 200, 400, 800, 1600, 3200, 6400
Direct Exposure Value
Set exposure directly (useful for matching other engines):
// EV of 1.0 sets aperture=1.0, shutter=1.2, sensitivity=100
camera -> setExposure ( 1.0 f );
// Brighter
camera -> setExposure ( 2.0 f );
// Darker
camera -> setExposure ( 0.5 f );
Reading Exposure Values
float aperture = camera -> getAperture ();
float shutter = camera -> getShutterSpeed ();
float iso = camera -> getSensitivity ();
Depth of Field
Configure camera focus for depth of field effects:
// Set focus distance
camera -> setFocusDistance ( 5.0 f ); // Focus at 5 meters
// Get focus distance
float focus = camera -> getFocusDistance ();
// Get focal length
double focalLength = camera -> getFocalLength (); // In meters
Focus distance must be larger than the near clipping plane. See Post-Processing for DOF effect configuration.
Focal Length Utilities
// Compute effective focal length
double effectiveFocal = Camera :: computeEffectiveFocalLength (
28.0 , // Focal length (mm)
5.0 // Focus distance (m)
);
// Compute effective FOV
double effectiveFov = Camera :: computeEffectiveFov (
45.0 , // FOV in degrees
5.0 // Focus distance (m)
);
Viewport Scaling and Shifting
Scaling
Scale the projection independently of aspect ratio:
// Set aspect to 1.0 in projection
camera -> setProjection ( 45.0 , 1.0 , 0.1 , 100.0 );
// Scale for actual aspect
double aspect = width / height;
camera -> setScaling ({ 1.0 / aspect, 1.0 }); // Vertical FOV
// OR
camera -> setScaling ({ 1.0 , aspect}); // Horizontal FOV
// Get current scaling
math ::double4 scaling = camera -> getScaling ();
Shifting
Translate the projection (useful for tiled rendering, VR):
// Shift in NDC coordinates
camera -> setShift ({ 0.1 , 0.0 }); // Shift right by 10% of viewport
// For pixel-perfect shift
float pixelX = 10.0 f ;
float pixelY = 5.0 f ;
camera -> setShift ({
pixelX / viewportWidth,
pixelY / viewportHeight
});
// Get current shift
math ::double2 shift = camera -> getShift ();
Stereoscopic Rendering
Configure multi-eye rendering for VR/AR:
// Set eye transforms relative to head (camera transform)
math ::mat4 leftEye = math :: mat4 :: translation ({ - 0.03 , 0 , 0 }); // 3cm left
math ::mat4 rightEye = math :: mat4 :: translation ({ 0.03 , 0 , 0 }); // 3cm right
camera -> setEyeModelMatrix ( 0 , leftEye);
camera -> setEyeModelMatrix ( 1 , rightEye);
// Set per-eye projections
math ::mat4 eyeProjections [ 2 ] = {leftProj, rightProj};
math ::mat4 cullingProj = ...; // Must encompass both eyes
camera -> setCustomEyeProjection (
eyeProjections,
2 , // Eye count
cullingProj,
0.1 , // Near
100.0 // Far
);
Stereoscopic eye count is set in Engine::Config::stereoscopicEyeCount (default: 2).
Inverse Projection
Convert from screen/NDC space back to view/world space:
// Get inverse projection matrix
math ::mat4 proj = camera -> getProjectionMatrix ();
math ::mat4 invProj = Camera :: inverseProjection (proj);
// Transform screen coordinates to view space
math ::float3 ndcPos = {screenX / width * 2 - 1 ,
screenY / height * 2 - 1 ,
depth * 2 - 1 };
math ::float4 viewPos = invProj * math :: float4 (ndcPos, 1.0 );
viewPos /= viewPos . w ; // Perspective divide
// Transform to world space
math ::mat4 invView = camera -> getModelMatrix ();
math ::float4 worldPos = invView * viewPos;
Destroying Cameras
Cameras must be explicitly destroyed:
// Dissociate from view
view -> setCamera ( nullptr );
// Destroy camera component
utils ::Entity entity = camera -> getEntity ();
engine -> destroyCameraComponent (entity);
// Destroy entity
utils :: EntityManager :: get (). destroy (entity);
Complete Example
// Create camera
utils ::Entity cameraEntity = utils :: EntityManager :: get (). create ();
Camera * camera = engine -> createCamera (cameraEntity);
// Configure projection
camera -> setProjection (
45.0 , // 45 degree FOV
16.0 / 9.0 , // 16:9 aspect
0.1 , // 10cm near plane
100.0 , // 100m far plane
Camera :: Fov ::VERTICAL
);
// Set exposure (outdoor sunny day)
camera -> setExposure (
16.0 f , // f/16
1.0 f / 125.0 f , // 1/125s
100.0 f // ISO 100
);
// Position camera
camera -> lookAt (
{ 0 , 1.6 , 5 }, // Eye at 1.6m height, 5m back
{ 0 , 1 , 0 }, // Looking at 1m height
{ 0 , 1 , 0 } // Up is +Y
);
// Set focus for DOF
camera -> setFocusDistance ( 5.0 f );
// Assign to view
view -> setCamera (camera);
Best Practices
Depth Precision
Use highest possible near plane value
Keep near:far ratio reasonable (1:100 to 1:100000)
Prefer 1.0m near for large outdoor scenes
Use 0.1m near for indoor scenes
Exposure
Default settings work well for outdoor scenes with strong directional light
Indoor scenes need wider aperture and higher ISO
Match light intensity to exposure (100,000 lux sun with f/16, 1/125, ISO 100)
Adjust exposure, not light intensity, for artistic brightness
Minimize projection matrix changes
Avoid setting transform every frame if camera is static
Use frustum culling (enabled by default)
Cache computed values (matrices, vectors)
Next Steps
Post-Processing Configure DOF and other camera-related effects
Lighting Set up lights that work with camera exposure