Skip to main content

Renderer

A Renderer instance represents an operating system’s window and manages frame rendering.

Overview

Applications typically create one Renderer per window. The Renderer generates drawing commands for the render thread and manages frame latency.

Creation and destruction

Create using Engine::createRenderer() and destroy using Engine::destroy():
#include <filament/Renderer.h>
#include <filament/Engine.h>
using namespace filament;

Engine* engine = Engine::create();

Renderer* renderer = engine->createRenderer();
// ... use renderer ...
engine->destroy(renderer);

Rendering a frame

The basic rendering pattern:
if (renderer->beginFrame(swapChain)) {
    renderer->render(view);
    renderer->endFrame();
}

beginFrame

swapChain
SwapChain*
The swap chain to render into
vsyncSteadyClockTimeNano
uint64_t
default:"0"
Optional VSYNC timestamp for frame pacing (default: 0 = current time)
Returns true if rendering should proceed, false if the frame should be skipped.
// Basic usage
if (renderer->beginFrame(swapChain)) {
    // Render frame
}

// With VSYNC timestamp for frame pacing
uint64_t vsyncTime = getVsyncTimestamp();
if (renderer->beginFrame(swapChain, vsyncTime)) {
    // Render frame
}

render

view
View*
The view to render
Renders a view into the current swap chain:
renderer->render(view);

endFrame

Completes the frame and presents to the swap chain:
renderer->endFrame();
Always call endFrame() after beginFrame() returns true, even if you don’t call render().

Display configuration

Set display info

refreshRate
float
default:"60.0f"
Display refresh rate in Hz (0 for offscreen or to disable frame pacing)
Renderer::DisplayInfo displayInfo;
displayInfo.refreshRate = 120.0f;  // 120 Hz display

renderer->setDisplayInfo(displayInfo);

Set frame rate

Configure frame rate and dynamic resolution scaling:
Renderer::FrameRateOptions options;
options.interval = 1;           // Render every frame
options.headRoomRatio = 0.0f;   // No headroom
options.scaleRate = 0.125f;     // React to load changes
options.history = 15;           // History size

renderer->setFrameRateOptions(options);

Clear options

Control swap chain clearing:
Renderer::ClearOptions clearOptions;
clearOptions.clearColor = {0.1f, 0.1f, 0.1f, 1.0f};  // Dark gray
clearOptions.clear = true;          // Clear the swap chain
clearOptions.discard = true;        // Discard previous content
clearOptions.clearStencil = 0;

if (renderer->beginFrame(swapChain)) {
    renderer->setClearOptions(clearOptions);
    renderer->render(view);
    renderer->endFrame();
}
clearColor
float4
sRGB linear color to clear with (not tone-mapped)
clear
bool
default:"false"
Whether to clear the swap chain
discard
bool
default:"true"
Whether to discard previous content (clear implies discard)
The clear color is not tone-mapped. For consistent results, use a Skybox or set clear color to black/transparent.

Frame timing

Get frame timing information:
// Get last frame info
auto frameInfo = renderer->getFrameInfoHistory(1);
if (!frameInfo.empty()) {
    Renderer::FrameInfo& info = frameInfo[0];
    double gpuTimeMs = info.gpuFrameDuration / 1e6;
    std::cout << "GPU time: " << gpuTimeMs << " ms" << std::endl;
}

// Get frame history (up to maximum)
size_t maxHistory = renderer->getMaxFrameHistorySize();
auto history = renderer->getFrameInfoHistory(maxHistory);

FrameInfo structure

frameId
uint32_t
Monotonically increasing frame identifier
gpuFrameDuration
int64_t
Frame duration on GPU in nanoseconds
denoisedGpuFrameDuration
int64_t
Denoised GPU frame duration in nanoseconds
beginFrame
int64_t
beginFrame() timestamp since epoch (ns)
endFrame
int64_t
endFrame() timestamp since epoch (ns)
vsync
int64_t
VSYNC timestamp since epoch (ns)

Rendering multiple views

You can render multiple views in a single frame:
if (renderer->beginFrame(swapChain)) {
    renderer->render(mainView);
    renderer->render(uiView);
    renderer->endFrame();
}

Mirror mode

Render the same view to multiple swap chains:
Renderer::ClearOptions clearOptions;
clearOptions.clear = true;

if (renderer->beginFrame(swapChain1)) {
    renderer->setClearOptions(clearOptions);
    renderer->render(view);
    
    // Copy to mirror swap chain
    renderer->copyFrame(swapChain2, 
                       Renderer::CopyFrameFlag::SET_PRESENTATION_TIME);
    
    renderer->endFrame();
}

Performance tips

Set correct display refresh rate for optimal frame pacing:
Renderer::DisplayInfo info;
info.refreshRate = 120.0f;  // Match actual display
renderer->setDisplayInfo(info);
Respect beginFrame() return value:
if (renderer->beginFrame(swapChain)) {
    // Only render if needed
    renderer->render(view);
    renderer->endFrame();
}
Configure frame rate options for dynamic resolution:
Renderer::FrameRateOptions options;
options.scaleRate = 0.125f;  // React quickly to load
renderer->setFrameRateOptions(options);

Engine

Main entry point

View

Rendering configuration

SwapChain

Native window binding

Rendering loop

Learn the render loop

Build docs developers (and LLMs) love