Skip to main content
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.
Skybox::Builder builder;

environment

Set the environment map (i.e., the skybox content).
cubemap
Texture*
required
A cubemap texture. The cmgen tool generates reflection maps ideal for skyboxes
return
Builder&
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.
show
bool
default:"false"
True if the sun should be rendered, false otherwise
return
Builder&
This Builder, for chaining calls
builder.showSun(true);
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.
envIntensity
float
default:"30000"
Scale factor applied to the skybox texel values such that the result is in lux (lumen/m²)
return
Builder&
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
return
Builder&
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
uint8_t
default:"7"
Priority value, clamped to range [0..7]. 7 is lowest priority (rendered last)
return
Builder&
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.
engine
Engine&
required
Reference to the filament::Engine to associate this Skybox with
return
Skybox*
Pointer to the newly created object
Skybox* skybox = builder.build(*engine);

Instance Methods

setColor

Sets the skybox to a constant color.
color
math::float4
required
The constant color (RGBA)
skybox->setColor({0.5f, 0.7f, 1.0f, 1.0f});

setLayerMask

Sets bits in a visibility mask.
select
uint8_t
required
The set of bits to affect
values
uint8_t
required
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.
return
uint8_t
The layer mask bits
uint8_t mask = skybox->getLayerMask();

getIntensity

Returns the skybox’s intensity in lux (lumen/m²).
return
float
Intensity in lux
float intensity = skybox->getIntensity();

getTexture

Returns the associated texture.
return
Texture*
The cubemap 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

  1. Use cmgen to generate properly formatted cubemaps for skyboxes
  2. Match with IndirectLight - Use skybox textures generated alongside IBL data for consistent lighting
  3. Set appropriate intensity - When no IndirectLight is used, adjust skybox intensity to match your scene
  4. Enable sun rendering when using a Type::SUN light for a more realistic outdoor scene
  5. Use layer masks to control skybox visibility across different views
  6. 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

Build docs developers (and LLMs) love