When added to a Scene, the Skybox fills all untouched pixels.
A Skybox is rendered as though it were an infinitely large cube with the camera inside it, providing a backdrop for your 3D scene.
Overview
The Skybox is mapped onto a cube’s exterior which will appear mirrored, following OpenGL conventions. The cmgen tool generates reflection maps by default which are ideal for use as skyboxes.
Currently only Texture-based skyboxes are supported.
Creation and Destruction
A Skybox object is created using the Skybox::Builder and destroyed by calling Engine::destroy(const Skybox*).
filament::Engine* engine = filament::Engine::create();
filament::Skybox* skybox = filament::Skybox::Builder()
.environment(cubemap)
.build(*engine);
engine->destroy(skybox);
Builder Methods
Constructor
Creates a Skybox builder.
environment
Set the environment map (i.e., the skybox content).
A cubemap texture. The cmgen tool generates reflection maps ideal for skyboxes
This Builder, for chaining calls
Texture* cubemap = ...; // Load your cubemap texture
builder.environment(cubemap);
The Skybox is rendered as though it were an infinitely large cube with the camera inside it. The cubemap mapped onto the cube’s exterior will appear mirrored, following OpenGL conventions.
showSun
Indicates whether the sun should be rendered.
True if the sun should be rendered, false otherwise
This Builder, for chaining calls
The sun can only be rendered if there is at least one light of type SUN in the scene.
intensity
Skybox intensity when no IndirectLight is set on the Scene.
Scale factor applied to the skybox texel values such that the result is in lux (lumen/m²)
This Builder, for chaining calls
builder.intensity(30000.0f);
This call is ignored when an IndirectLight is set on the Scene - the intensity of the IndirectLight is used instead.
color
Sets the skybox to a constant color.
color
math::float4
default:"{0, 0, 0, 1}"
The constant color (RGBA). Default is opaque black
This Builder, for chaining calls
// Light blue sky
builder.color({0.5f, 0.7f, 1.0f, 1.0f});
Ignored if an environment cubemap is set.
priority
Set the rendering priority of the Skybox.
Priority value, clamped to range [0..7]. 7 is lowest priority (rendered last)
This Builder, for chaining calls
builder.priority(7); // Render last (default)
By default, the Skybox has the lowest priority (7) so it’s always rendered after opaque objects, reducing overdraw when depth culling is enabled.
build
Creates the Skybox object and returns a pointer to it.
Reference to the filament::Engine to associate this Skybox with
Pointer to the newly created object
Skybox* skybox = builder.build(*engine);
Instance Methods
setColor
Sets the skybox to a constant color.
The constant color (RGBA)
skybox->setColor({0.5f, 0.7f, 1.0f, 1.0f});
setLayerMask
Sets bits in a visibility mask.
The set of bits to affect
The replacement values for the affected bits
// Set bit 1 and reset bits 0 and 2, leaving other bits unaffected
skybox->setLayerMask(7, 2);
This provides a simple mechanism for hiding or showing this Skybox in a Scene. By default, the layer mask is 0x1.
getLayerMask
Returns the visibility mask bits.
uint8_t mask = skybox->getLayerMask();
getIntensity
Returns the skybox’s intensity in lux (lumen/m²).
float intensity = skybox->getIntensity();
getTexture
Returns the associated texture.
Texture* texture = skybox->getTexture();
Complete Examples
Basic Skybox with Cubemap
#include <filament/Engine.h>
#include <filament/Scene.h>
#include <filament/Skybox.h>
#include <filament/Texture.h>
using namespace filament;
Engine* engine = Engine::create();
Scene* scene = engine->createScene();
// Load cubemap texture (e.g., generated by cmgen)
Texture* cubemap = ...; // Your cubemap loading code
// Create skybox
Skybox* skybox = Skybox::Builder()
.environment(cubemap)
.showSun(true)
.build(*engine);
// Add to scene
scene->setSkybox(skybox);
// Don't forget to destroy when done
engine->destroy(skybox);
Skybox with Constant Color
// Create a simple blue sky without a texture
Skybox* skybox = Skybox::Builder()
.color({0.53f, 0.81f, 0.92f, 1.0f}) // Light blue
.build(*engine);
scene->setSkybox(skybox);
Skybox with IndirectLight
#include <filament/Engine.h>
#include <filament/Scene.h>
#include <filament/Skybox.h>
#include <filament/IndirectLight.h>
#include <filament/LightManager.h>
using namespace filament;
using namespace math;
Engine* engine = Engine::create();
Scene* scene = engine->createScene();
// Load textures (generated by cmgen)
Texture* reflectionMap = ...; // environment_ibl.ktx
Texture* skyboxMap = ...; // environment_skybox.ktx
// Load spherical harmonics
float3 sh[9] = { /* ... from cmgen output ... */ };
// Create IndirectLight
IndirectLight* ibl = IndirectLight::Builder()
.reflections(reflectionMap)
.irradiance(3, sh)
.intensity(30000.0f)
.build(*engine);
// Create Skybox
Skybox* skybox = Skybox::Builder()
.environment(skyboxMap)
.showSun(true)
.build(*engine);
// Add to scene
scene->setIndirectLight(ibl);
scene->setSkybox(skybox);
// Create sun light
utils::Entity sunEntity = utils::EntityManager::get().create();
float3 sunDir = ibl->getDirectionEstimate();
float4 sunColor = ibl->getColorEstimate(sunDir);
LightManager::Builder(LightManager::Type::SUN)
.direction(sunDir)
.color({sunColor.x, sunColor.y, sunColor.z})
.intensity(sunColor.w * ibl->getIntensity())
.castShadows(true)
.build(*engine, sunEntity);
scene->addEntity(sunEntity);
Dynamic Skybox Visibility
// Show skybox only on layers 0 and 1
skybox->setLayerMask(0xFF, 0x03); // Affect all bits, set bits 0 and 1
// In your view, show only layer 0
view->setVisibleLayers(0x01, 0x01);
// The skybox will be visible because both the view and skybox have layer 0 enabled
Animated Skybox Rotation
// Skybox itself doesn't have rotation, but you can rotate the IndirectLight
// which affects both the lighting and skybox if they use the same texture
float angle = 0.0f;
while (rendering) {
angle += 0.01f; // Rotate over time
math::mat3f rotation = math::mat3f::rotation(
angle,
math::float3{0, 1, 0} // Rotate around Y axis
);
ibl->setRotation(rotation);
// Render frame...
}
Using cmgen for Skybox
The cmgen tool can generate skybox textures from HDR environment maps:
# Generate both IBL and skybox from an HDR image
cmgen -x . --format=ktx --size=256 --extract-blur=0.1 environment.hdr
# This generates:
# - environment_ibl.ktx (for IndirectLight reflections)
# - environment_skybox.ktx (for Skybox)
# - environment.txt (spherical harmonics for IndirectLight)
Then load in your application:
Texture* iblTexture = loadKtxTexture("environment_ibl.ktx");
Texture* skyboxTexture = loadKtxTexture("environment_skybox.ktx");
IndirectLight* ibl = IndirectLight::Builder()
.reflections(iblTexture)
.build(*engine);
Skybox* skybox = Skybox::Builder()
.environment(skyboxTexture)
.build(*engine);
scene->setIndirectLight(ibl);
scene->setSkybox(skybox);
Best Practices
- Use cmgen to generate properly formatted cubemaps for skyboxes
- Match with IndirectLight - Use skybox textures generated alongside IBL data for consistent lighting
- Set appropriate intensity - When no IndirectLight is used, adjust skybox intensity to match your scene
- Enable sun rendering when using a Type::SUN light for a more realistic outdoor scene
- Use layer masks to control skybox visibility across different views
- Default priority is optimal - The default priority of 7 ensures the skybox renders last, minimizing overdraw
- IndirectLight - For environment-based lighting
- LightManager - For creating sun lights that can be visualized in the skybox
- Camera - For controlling the view of the skybox