Skip to main content
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 1mPrecision at 10mPrecision at 100m
0.0017.2e-50.00430.4624
0.016.9e-60.00010.0430
0.13.6e-77.0e-50.0072
1.003.8e-60.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.

Camera Transform

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.0f,     // Aperture (f-stop)
    1.0/125.0, // Shutter speed (seconds)
    100.0f     // Sensitivity (ISO)
);

// Indoor scene
camera->setExposure(
    2.8f,      // Wide aperture (more light)
    1.0/60.0,  // Slower shutter
    400.0f     // Higher ISO
);

// Night scene
camera->setExposure(
    1.8f,      // Very wide aperture
    1.0/30.0,  // Slow shutter
    1600.0f    // 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.0f);

// Brighter
camera->setExposure(2.0f);

// Darker  
camera->setExposure(0.5f);

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.0f);  // 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.0f;
float pixelY = 5.0f;
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.0f,         // f/16
    1.0f / 125.0f, // 1/125s
    100.0f         // 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.0f);

// 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

Performance

  • 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

Build docs developers (and LLMs) love