Qt Quick 3D - Volumetric Light Example
Demonstrates how the QtQuick3D Render Extension can be used to implement volumetric light.

Overview
This example shows how to use QtQuick3D Render Extension to make a volumetric light extension and how can it be use as a component in a project.
Controls
For navigation, you can orbit around the scene and you can use settings panel to change lights, volumetric fog and scene settings.
Implementation
The Volumetric fog extension is implemented in the VolumetricFogExtension. This is located in the separate sub-project VFExtension, so you can easily re-use it in other projects.
The VolumetricFogExtension has the following properties that need to be set:
VolumetricFogExtension {
id: froxelExtension
froxelWidth: 160
froxelHeight: 96
froxelDepth: 96
nearPlane: 1.0
farPlane: 4000.0
fogVolumes: [ fogSphere ]
iesTexture: settings.iesLights ? iesAtlasTexture : null
iesCount: iesTextureData.sources.length
iesLightProfiles: [
IESLightProfileIndex { light: pinkSpot; index: settings.iesLightIndex; intensity: 0.5}
]
}The froxelWidth, froxelHeight, and froxelDepth properties define the resolution of the 3D froxel grid used by the volumetric compute shader. Higher resolution produces more detailed light scattering at the cost of GPU memory and compute time.
The nearPlane and farPlane properties define the depth range over which the volumetric effect is computed, and should match the PerspectiveCamera's clip distances.
The fogVolumes property holds a list of Fog3DVolume nodes that define where volumetric fog is present in the scene.
IES Light Profiles
IES light profiles can be used to shape the angular light distribution of spot lights. The iesTexture property takes a Texture whose data is generated by an IESTextureData object that parses .ies files and packs them into a 2D atlas texture. The iesCount property specifies how many profiles are packed in the atlas, and iesLightProfiles maps individual lights to profile indices via IESLightProfileIndex objects.
Texture {
id: iesAtlasTexture
textureData: IESTextureData {
id: iesTextureData
sources: [
"qrc:/assets/l0.ies",
"qrc:/assets/l1.ies",
"qrc:/assets/l2.ies",
"qrc:/assets/l3.ies",
"qrc:/assets/l4.ies",
"qrc:/assets/l5.ies"
]
}
tilingModeHorizontal: Texture.ClampToEdge
tilingModeVertical: Texture.ClampToEdge
minFilter: Texture.Linear
magFilter: Texture.Linear
generateMipmaps: false
}Attaching the Extension to a View3D
The extension is registered with the View3D through its extensions property, which lets the render pipeline invoke the extension's compute shader each frame:
View3D {
extensions: [ froxelExtension ]
}Fog Volumes
Fog regions are defined using Fog3DVolume nodes placed in the scene. Each volume supports two shapes via the type property: Fog3DVolume.Sphere and Fog3DVolume.Box. The extents property defines the bounding dimensions, while color and density control the visual appearance.
Animated noise is applied by advancing noiseOffset each frame. Height-based density falloff can be enabled with heightEnabled together with leastIntenseY, mostIntenseY, and heightCurve:
Fog3DVolume {
id: fogSphere
type: Fog3DVolume.Sphere
extents: Qt.vector3d(5000, 5000, 5000)
color: settings.fogVolumeColor
density: settings.fogVolumeDensity
noiseOffset: Qt.vector3d(se.time * 0.1 * settings.fogSpeed, 0, 0)
noiseScale: settings.fogVolumeNoiseScale
heightEnabled: settings.fogVolumeHeightEnabled
leastIntenseY: settings.fogVolumeHeightLeastY
mostIntenseY: settings.fogVolumeHeightMostY
heightCurve: settings.fogVolumeHeightCurve
}VolumetricFogEffect
The extension exposes its result through the read-only froxelTexture property, a 3D RGBA texture containing the accumulated light scattering data for each froxel. This texture is consumed by the VolumetricFogEffect post-processing effect added to the ExtendedSceneEnvironment. The effect ray-marches through the froxel texture and composites the volumetric light onto the rendered frame:
environment: ExtendedSceneEnvironment {
effects: [
VolumetricFogEffect {
froxelTexture: froxelExtension.froxelTexture
cameraPosition: camera.scenePosition
cameraForward: camera.forward
invViewMatrix: camera.sceneTransform
marchSteps: froxelExtension.froxelDepth
nearPlane: froxelExtension.nearPlane
farPlane: froxelExtension.farPlane
frameBaseJitter: se.temporalAAEnabled &&
se.temporalAAMode === SceneEnvironment.TAAMotionVector &&
se.antialiasingMode !== SceneEnvironment.MSAA ? 1.0 : 0.0
jitterIntensity: settings.jitterIntensity
}
]
}The marchSteps property controls the number of ray marching steps and should match froxelDepth. The frameBaseJitter and jitterIntensity properties enable temporal dithering to reduce banding artifacts when used together with temporal anti-aliasing.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.