Qt Quick 3D - 体积雾扩展示例
演示如何在渲染扩展中实现体积雾。

概述
本示例将体积雾作为Qt Quick 3D render extension 实现,并演示了如何在您的项目中复用该扩展。
该扩展将摄像机锥体划分为由“froxel”(与锥体对齐的体素)组成的3D网格,并利用计算着色器累加每个单元格中向摄像机方向散射的光线。随后,后处理效果将结果合成到渲染帧上。
控制
使用鼠标拖动可在场景中环绕摄像机旋转。通过设置面板可调整照明、雾效、后处理及阴影设置。
实现
注意:该扩展 通过计算着色器将光线注入“froxel”网格,因此需要支持计算着色器的图形 API 和硬件。早于 4.3 版的 OpenGL 以及早于 3.1 版的 OpenGL ES 均不支持计算着色器。详情请参阅QRhi::Compute 。
VolumetricFogExtension 类型实现了体积雾扩展。它位于独立的VFExtension 子项目中,因此您可以直接将其添加到自己的项目中,无需进行任何修改。
在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}
]
}froxelWidth 、froxelHeight 和froxelDepth 属性定义了计算着色器填充的 Froxel 网格的分辨率。分辨率越高,光线散射效果越细腻,但会消耗更多的 GPU 内存和计算时间。
nearPlane 和farPlane 属性定义了体积效果所覆盖的深度范围。请将其与PerspectiveCamera 的裁剪距离相匹配。
fogVolumes 属性包含Fog3DVolume 节点的列表,这些节点定义了场景中雾气的存在位置。
IES 光照曲线
来自照明工程学会(IES)的光度分布曲线用于塑造聚光灯的光束角分布。iesTexture 属性接收一个Texture ,其数据来源于IESTextureData 对象。该对象负责解析.ies 文件,并将它们打包成一个2D图集纹理。iesCount 属性指定图集包含多少条分布曲线,而iesLightProfiles 则通过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
}将扩展程序附加到 View3D
将该扩展添加到View3D 的extensions 列表中。随后,渲染管线将每帧调用一次该扩展的计算着色器:
View3D {
extensions: [ froxelExtension ]
}雾体积
Fog3DVolume 节点用于在场景中定义雾区。type 属性可选择两种形状之一:Fog3DVolume.Sphere 或Fog3DVolume.Box ,而extents 属性则用于设置边界尺寸。color 和density 属性用于控制外观效果。
每帧将 `noiseOffset ` 值递增可实现噪点动画效果。若要使密度随高度递减,请将 `heightEnabled ` 设置为 `true `,并调整 `leastIntenseY`、`mostIntenseY` 和 `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
该扩展通过只读属性froxelTexture 展示其结果,这是一个 3D RGBA 纹理,其中存储了每个 Froxel 的累积光散射数据。将VolumetricFogEffect 后处理效果添加到ExtendedSceneEnvironment 上,以使用该纹理。该效果通过 Froxel 纹理进行光线行进,并将体积光合成到渲染帧中:
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
}
]marchSteps 属性控制光线行进的步数。请将其与froxelDepth 设置保持一致。frameBaseJitter 和jitterIntensity 属性可启用时间抖动,当场景同时使用时间抗锯齿时,该功能可减少带状伪影。
在您自己的项目中复用该扩展
VFExtension 子项目可作为独立的QML模块进行构建。若要在其他项目中使用它,请复制该目录,通过add_subdirectory() 将其添加,并将该库链接到目标项目中:
add_subdirectory(VFExtension)
target_link_libraries(myapp PRIVATE VFExtension)然后在 QML 中导入该模块:
import VFExtension注意:该 扩展包含私有Qt Quick 3D 头文件,并链接自Qt6::Quick3DPrivate 。私有API不保证源代码或二进制兼容性,因此当您升级到新版Qt时,该扩展可能需要进行修改。
另请参阅 Qt Quick 3D - 模板轮廓扩展示例、Qt Quick 3D - 简单雾效示例,以及 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.