Revision control

++ // Copyright (C) 2026 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
++
++ /*!
++ \example extensions/volumetricfog
++ \ingroup quick3d-examples
++ \title Qt Quick 3D - Volumetric Fog Extension Example
++ \examplecategory {3D}
++ \brief Demonstrates how to implement volumetric fog in a render extension.
++ \image volumetric-fog-example.webp
++ {Bare tree on a round tiered stage lit by red, green, and blue
++ volumetric light beams, with a settings panel for lights, fog,
++ and shadows}
++
++ \section1 Overview
++
++ This example implements volumetric fog as a Qt Quick 3D
++ \l{QQuick3DRenderExtension}{render extension}, and shows how to reuse the
++ extension in your own project.
++
++ The extension divides the camera frustum into a 3D grid of \e{froxels},
++ frustum-aligned voxels, and uses a compute shader to accumulate the light
++ that scatters toward the camera in each cell. A post-processing effect then
++ composites the result onto the rendered frame.
++
++ \section1 Controls
++
++ Drag with the mouse to orbit the camera around the scene. Use the settings
++ panel to change the lighting, the fog, the post-processing, and the shadow
++ settings.
++
++ \section1 Implementation
++
++ \note The extension injects light into the froxel grid with a compute
++ shader, so it requires a graphics API and hardware with compute
++ shader support. OpenGL versions older than 4.3 and OpenGL ES
++ versions older than 3.1 have no compute support. See
++ \l QRhi::Compute for details.
++
++ The \c VolumetricFogExtension type implements the volumetric fog extension.
++ It lives in the separate \c VFExtension subproject, so you can add it to
++ your own project unchanged.
++
++ Set the following properties on \c VolumetricFogExtension:
++
++ \snippet extensions/volumetricfog/Main.qml fog extension
++
++ The \c froxelWidth, \c froxelHeight, and \c froxelDepth properties define
++ the resolution of the froxel grid that the compute shader fills. A higher
++ resolution produces more detailed light scattering, but uses more GPU
++ memory and compute time.
++
++ The \c nearPlane and \c farPlane properties define the depth range that the
++ volumetric effect covers. Match them to the clip distances of the
++ \l PerspectiveCamera.
++
++ The \c fogVolumes property holds the list of \c Fog3DVolume nodes that
++ define where fog is present in the scene.
++
++ \section2 IES Light Profiles
++
++ A photometric profile from the Illuminating Engineering Society (IES)
++ shapes the angular light distribution of a spot light. The \c iesTexture
++ property takes a \l Texture whose data comes from an \c IESTextureData
++ object. That object parses \c{.ies} files and packs them into a 2D atlas
++ texture. The \c iesCount property specifies how many profiles the atlas
++ holds, and \c iesLightProfiles maps individual lights to profile indices
++ through \c IESLightProfileIndex objects.
++
++ \snippet extensions/volumetricfog/Main.qml ies texture
++
++ \section2 Attaching the Extension to a View3D
++
++ Add the extension to the \l{View3D::extensions}{extensions} list of the
++ \l View3D. The render pipeline then invokes the extension's compute shader
++ once per frame:
++
++ \qml
++ View3D {
++ extensions: [ froxelExtension ]
++ }
++ \endqml
++
++ \section2 Fog Volumes
++
++ A \c Fog3DVolume node defines a fog region in the scene. The \c type
++ property selects one of two shapes, \c{Fog3DVolume.Sphere} or
++ \c{Fog3DVolume.Box}, and the \c extents property sets the bounding
++ dimensions. The \c color and \c density properties control the appearance.
++
++ Advancing \c noiseOffset each frame animates the noise. To make the density
++ fall off with height, set \c heightEnabled to \c true and adjust
++ \c leastIntenseY, \c mostIntenseY, and \c heightCurve:
++
++ \snippet extensions/volumetricfog/Main.qml fog volume
++
++ \section2 VolumetricFogEffect
++
++ The extension exposes its result through the read-only \c froxelTexture
++ property, a 3D RGBA texture that holds the accumulated light scattering
++ data for each froxel. Add the \c VolumetricFogEffect post-processing effect
++ to the \l ExtendedSceneEnvironment to consume that texture. The effect
++ ray-marches through the froxel texture and composites the volumetric light
++ onto the rendered frame:
++
++ \snippet extensions/volumetricfog/Main.qml fog effect
++
++ The \c marchSteps property controls the number of ray marching steps. Match
++ it to \c froxelDepth. The \c frameBaseJitter and \c jitterIntensity
++ properties enable temporal dithering, which reduces banding artifacts when
++ the scene also uses temporal antialiasing.
++
++ \section1 Reusing the Extension in Your Own Project
++
++ The \c VFExtension subproject builds as a QML module of its own. To use it
++ in another project, copy the directory, add it with
++ \c{add_subdirectory()}, and link the library into your target:
++
++ \badcode
++ add_subdirectory(VFExtension)
++
++ target_link_libraries(myapp PRIVATE VFExtension)
++ \endcode
++
++ Then import the module in QML:
++
++ \qml
++ import VFExtension
++ \endqml
++
++ \note The extension includes private Qt Quick 3D headers and links against
++ \c Qt6::Quick3DPrivate. Private API carries no source or binary
++ compatibility guarantee, so the extension may need changes when you
++ move to a newer Qt version.
++
++ \sa {Qt Quick 3D - Stencil Outline Extension Example},
++ {Qt Quick 3D - Simple Fog Example},
++ {User-Defined Render Passes in Qt Quick 3D}
++ */