Sur cette page

Qt Quick 3D - Exemple d'extension de brouillard volumétrique

Illustre comment implémenter un brouillard volumétrique dans une extension de rendu.

Arbre nu sur une scène ronde à plusieurs niveaux, éclairé par des faisceaux lumineux volumétriques rouges, verts et bleus, avec un panneau de réglages pour les lumières, le brouillard et les ombres

Présentation

Cet exemple implémente le brouillard volumétrique sous la forme d’une extension de rendu 3D Qt Quick render extension et montre comment réutiliser cette extension dans votre propre projet.

L’extension divise le frustum de la caméra en une grille 3D de « froxels » (voxels alignés sur le frustum) et utilise un shader de calcul pour accumuler la lumière qui se diffuse vers la caméra dans chaque cellule. Un effet de post-traitement superpose ensuite le résultat à l’image rendue.

Commandes

Faites glisser la souris pour faire tourner la caméra autour de la scène. Utilisez le panneau de paramètres pour modifier les réglages d’éclairage, de brouillard, de post-traitement et d’ombres.

Mise en œuvre

Remarque : l’extension injecte de la lumière dans la grille de froxels à l’aide d’un shader de calcul ; elle nécessite donc une API graphique et du matériel prenant en charge les shaders de calcul. Les versions d’OpenGL antérieures à la version 4.3 et les versions d’OpenGL ES antérieures à la version 3.1 ne prennent pas en charge les shaders de calcul. Consultez QRhi::Compute pour plus de détails.

Le type ` VolumetricFogExtension ` implémente l’extension de brouillard volumétrique. Il se trouve dans le sous-projet distinct ` VFExtension ` ; vous pouvez donc l’ajouter tel quel à votre propre projet.

Définissez les propriétés suivantes sur VolumetricFogExtension:

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}
    ]
}

Les propriétés froxelWidth, froxelHeight et froxelDepth définissent la résolution de la grille de froxels que le shader de calcul remplit. Une résolution plus élevée produit une diffusion de la lumière plus détaillée, mais utilise davantage de mémoire GPU et de temps de calcul.

Les propriétés nearPlane et farPlane définissent la plage de profondeur couverte par l’effet volumétrique. Faites-les correspondre aux distances de découpe des nœuds PerspectiveCamera.

La propriété « fogVolumes » contient la liste des nœuds « Fog3DVolume » qui définissent les zones de la scène où le brouillard est présent.

Profils d’éclairage IES

Un profil photométrique de l’Illuminating Engineering Society (IES) définit la distribution angulaire de la lumière d’un projecteur. La propriété « iesTexture » prend en paramètre un nœud « Texture » dont les données proviennent d’un objet « IESTextureData ». Cet objet analyse les fichiers « .ies » et les regroupe dans une texture d’atlas 2D. La propriété « iesCount » spécifie le nombre de profils contenus dans l’atlas, tandis que « iesLightProfiles » associe chaque source lumineuse à un indice de profil via des objets « IESLightProfileIndex ».

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
}
Ajout de l’extension à une vue 3D

Ajoutez l’extension à la liste « extensions » de l’ View3D. Le pipeline de rendu appelle alors le shader de calcul de l’extension une fois par image :

View3D {
    extensions: [ froxelExtension ]
}
Volumes de brouillard

Un nœud « Fog3DVolume » définit une zone de brouillard dans la scène. La propriété « type » permet de choisir entre deux formes : « Fog3DVolume.Sphere » ou « Fog3DVolume.Box », tandis que la propriété « extents » définit les dimensions de la zone délimitée. Les propriétés « color » et « density » contrôlent l’apparence.

L'noiseOffset, qui s'incrémente à chaque image, anime le bruit. Pour que la densité diminue avec la hauteur, définissez heightEnabled sur true et ajustez leastIntenseY, mostIntenseY et heightCurve:

Fog3DVolume {
    id: fogSphere
    type: Fog3DVolume.Sphere
    extents: Qt.vector3d(5000, 5000, 5000)
    color: settings.fogVolumeColor
    density: settings.fogVolumeDensity
    noiseOffset: Qt.vector3d(baseNode.time * 0.1 * settings.fogSpeed,
                             baseNode.time * 0.02 * settings.fogSpeed,
                             baseNode.time * 0.01 * settings.fogSpeed)
    noiseScale: settings.fogVolumeNoiseScale
    heightEnabled: settings.fogVolumeHeightEnabled
    leastIntenseY: settings.fogVolumeHeightLeastY
    mostIntenseY: settings.fogVolumeHeightMostY
    heightCurve: settings.fogVolumeHeightCurve
}
VolumetricFogEffect

L’extension expose son résultat via la propriété en lecture seule froxelTexture, une texture RGBA 3D qui contient les données cumulées de diffusion de la lumière pour chaque froxel. Ajoutez l’effet de post-traitement VolumetricFogEffect à ExtendedSceneEnvironment pour utiliser cette texture. L’effet effectue un ray-marching à travers la texture de froxels et superpose la lumière volumétrique à l’image rendue :

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
    }
]

La propriété « marchSteps » contrôle le nombre d’étapes de ray-marching. Faites-la correspondre à « froxelDepth ». Les propriétés « frameBaseJitter » et « jitterIntensity » activent le dithering temporel, qui réduit les artefacts de bandes lorsque la scène utilise également l’anticrénelage temporel.

Réutilisation de l’extension dans votre propre projet

Le sous-projet « VFExtension » se compile en tant que module QML à part entière. Pour l’utiliser dans un autre projet, copiez le répertoire, ajoutez-le via add_subdirectory(), puis liez la bibliothèque à votre cible :

add_subdirectory(VFExtension)

target_link_libraries(myapp PRIVATE VFExtension)

Importez ensuite le module dans QML :

import VFExtension

Remarque : l’extension inclut des en-têtes 3D privés d’ Qt Quick et est liée à Qt6::Quick3DPrivate. L’API privée n’offre aucune garantie de compatibilité au niveau du code source ou des binaires ; l’extension pourra donc nécessiter des modifications si vous passez à une version plus récente de Qt.

Exemple de projet sur code.qt.io

Voir également « Exemple d’extension Stencil Outline pourQt Quick 3D », « Exemple de brouillard simple pourQt Quick 3D » et « Passes de rendu définies par l’utilisateur dans Qt Quick 3D ».

© 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.