Revision control

Copy as Markdown

// Copyright (C) 2026 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example skymaterial
\ingroup quick3d-examples
\title Qt Quick 3D - Sky Material Example
\examplecategory {3D}
\brief Demonstrates procedural sky rendering and image-based lighting with SkyMaterial.
\image skymaterial-example.webp
{Procedural atmospheric sky with PBR spheres reflecting the environment}
This example shows how to use \l SkyMaterial to render a procedural sky
and use the resulting cubemap as the light probe for image-based lighting
(IBL) on the scene's PBR materials.
The \c AdvancedSky helper is a \l SkyMaterial subclass implementing a
physically-based atmospheric scattering model following Hillaire's
"A Scalable and Production Ready Sky and Atmosphere Rendering Technique"
(2020), with configurable aerosols, ozone, eye altitude, and ray-marched
volumetric clouds.
\section1 Setting Up the Scene
The application uses \l ApplicationWindow with a \l View3D filling the
window. A settings panel overlays the left edge and slides in and out
when the toggle button is clicked. The relevant QtQuick3D imports are:
\snippet skymaterial/main.qml import
\section1 Defining the Sky Material
\c AdvancedSky is declared inside the View3D so it shares the same
\c skyLight \l Node (the sun):
\snippet skymaterial/main.qml advanced-sky
\c AdvancedSky is a \l SkyMaterial subclass defined in \c AdvancedSky.qml.
Its QML properties are automatically forwarded as uniforms to the fragment
shader.
\section1 Image-Based Lighting
Assigning the sky material to \l SceneEnvironment::skyMaterial uses the
procedurally rendered cubemap both as the visible background and as the
source for image-based lighting on the PBR materials in the scene:
\snippet skymaterial/main.qml environment
The smoothest sphere in the demo mirrors the procedural sky almost
perfectly; the rougher spheres show progressively blurred reflections,
produced by SkyMaterial's GGX prefilter chain over the procedural cubemap.
\section1 Choosing How the Sky Is Drawn
\l{SkyMaterial::}{skyboxMode} selects what SkyMaterial produces for the
visible background, independently of the IBL cube used for reflections:
\list
\li \c SkyMaterial.Cubemap samples the radiance cubemap (the same cube
used for image-based lighting), so for a static sky the cube is
rendered once and then sampled cheaply every frame. Background
sharpness is capped at \l{SkyMaterial::}{radianceMapSize}. This is
the lowest per-frame cost when only the camera moves.
\li The \c ScreenSpace modes evaluate the sky shader directly on screen
every frame — at full, half, or quarter resolution per axis. They
decouple the visible background from the IBL cube, giving a crisp
sky for dynamic conditions (a moving sun, animated volumetric
clouds) at the cost of a per-frame render. Lower scales trade
sharpness for speed.
\endlist
Switch the "Skybox mode" combo box in the settings panel to compare the
options live: the cubemap modes stay cheap but soften as the sun and clouds
move, while the screen-space modes track every change sharply.
\section1 Managing Frame Budget
\l{SkyMaterial::}{iblRenderFrames} spreads the IBL prefilter across several
frames: the same total \l{SkyMaterial::}{iblSampleCount} is integrated
incrementally, one slice per frame, until convergence. The default value of
\c 0 runs sample accumulation, normalization, and irradiance all in a single
frame. Setting it higher amortizes the prefilter cost, keeping the scene
responsive when IBL sample counts are high.
\section1 Animating the Sun
A \l FrameAnimation drives the sun back and forth across the horizon when
the "Animate sun" toggle is on. Each change in sun position invalidates the
IBL accumulator, but with \l{SkyMaterial::}{iblRenderFrames} set
appropriately the prefilter cost is spread across frames and no single frame
pays the full cost.
\snippet skymaterial/main.qml sun-animation
\section1 Settings Panel
The settings panel slides in and out over the \l View3D, toggled by the
button in the top-left corner of the viewport. It is divided into two
groups.
\section2 Sky
Controls for the sky appearance and clouds.
\list
\li \b{Animate sun} — runs a ping-pong sun sweep across the horizon.
\li \b{Cycle speed} — sweep speed for the sun animation.
\li \b{Sun elevation} — manual sun position in degrees (0° = dawn,
90° = noon, 180° = dusk).
\li \b{Enable clouds} — toggles ray-marched volumetric clouds.
\li \b{Cloud coverage} — fraction of the sky covered by clouds
(0 = clear, 1 = overcast).
\li \b{Animate wind} — drifts the cloud noise texture each frame,
continuously invalidating the IBL accumulator — a useful stress test
for the frame budget controls.
\endlist
\section2 Rendering
Controls that map directly to \l SkyMaterial base-class properties.
\list
\li \b{Skybox mode} — see \l{SkyMaterial::}{skyboxMode}.
\li \b{IBL render frames} — see \l{SkyMaterial::}{iblRenderFrames}.
\li \b{Enable IBL} — see \l{SkyMaterial::}{enableIBL}.
\li \b{IBL sample count} — see \l{SkyMaterial::}{iblSampleCount}.
\li \b{Radiance map size} — see \l{SkyMaterial::}{radianceMapSize}.
\endlist
The camera responds to standard \l WasdController navigation — W/A/S/D plus
mouse drag to look around. Tap the viewport to give it keyboard focus.
\sa {SkyMaterial}
\sa {SceneEnvironment}
*/