Volumetric & Atmosphere — Fog, Clouds & Sky体积与大气 — 雾、云与天空
The Atmosphere Stack — Four Layered Systems大气栈 — 四个分层系统
UE5's atmosphere rendering is composed of four independent but complementary systems, each handling a different scale and physical phenomenon. They are designed to work together: the sky atmosphere provides the background color, clouds float in that atmosphere, volumetric fog fills the near-camera region, and height fog provides a cheap baseline fallback.
UE5 的大气渲染由四个独立但互补的系统组成,每个系统处理不同尺度和物理现象。 它们被设计为协同工作:天空大气提供背景颜色,云在大气中飘浮, 体积雾填充相机附近区域,高度雾提供廉价的基础回退。
Exponential Height Fog — The Cheap Baseline指数高度雾 — 廉价基础方案
Exponential Height Fog applies an analytical fog formula during the final lighting composite. It uses no 3D volume and no ray marching — just a per-pixel formula based on view ray length and altitude. Cost: near-zero (a few ALU ops per pixel in the final composition pass).
指数高度雾在最终光照合成期间应用解析雾公式。 它不使用 3D 体积,也不使用光线步进——只是基于视线长度和高度的逐像素公式。 成本:接近零(最终合成通道中每像素几个 ALU 操作)。
// FogRendering.cpp — analytical exponential height fog // Fog density decreases exponentially with altitude: // ρ(h) = FogDensity × exp(-FogHeightFalloff × (h - FogHeight)) // Optical depth integral along view ray from camera to fragment: float ComputeExponentialFogIntegral( float3 ViewOrigin, float3 ViewDir, float RayLength, float FogDensity, float FogHeight, float FogHeightFalloff) { float StartH = ViewOrigin.z - FogHeight; float DeltaH = ViewDir.z * RayLength; if (abs(DeltaH) < 0.001f) // nearly horizontal ray return FogDensity * RayLength * exp(-FogHeightFalloff * StartH); // Analytical integral of exp(-k*h) over the ray: // = (exp(-k*H_start) - exp(-k*H_end)) / (k * DeltaH/RayLength) float k = FogHeightFalloff; return FogDensity * RayLength * (exp(-k * StartH) - exp(-k * (StartH + DeltaH))) / (k * DeltaH); } // Apply: OutColor = lerp(FogColor, SceneColor, exp(-OpticalDepth))
Key parameters: Fog Density, Fog Height (world Z where fog is thickest), Fog Height Falloff (how quickly density drops with altitude), Fog Cutoff Distance (no fog beyond this — useful for indoor scenes), Directional Inscattering (sun glow direction inside fog).
关键参数:Fog Density,Fog Height(雾最浓的世界 Z 高度),Fog Height Falloff(密度随高度下降的速度),Fog Cutoff Distance(超过此距离无雾——对室内场景有用),Directional Inscattering(雾内太阳光晕方向)。
Volumetric Fog — 3D Froxel Grid with Full Light Scattering体积雾 — 带完整光散射的 3D Froxel 网格
Volumetric Fog is UE5's physically accurate near-camera fog system. It uses the same froxel grid as the light culling system (see Lighting Architecture), but this time each voxel stores in-scattering radiance — the light scattered into the voxel from all scene lights. View rays are then integrated through this voxel radiance to produce the final volumetric appearance.
体积雾是 UE5 物理精确的近相机雾系统。 它使用与灯光剔除系统相同的 Froxel 网格(见光照架构), 但这次每个体素存储内散射辐射率——从所有场景灯光散射进体素的光线。 视线光线然后通过这个体素辐射率进行积分以产生最终的体积外观。
// VolumetricFog.cpp — key froxel grid parameters // Grid resolution (typical defaults) const int FogGridSizeX = 160; // screen-aligned columns const int FogGridSizeY = 90; // screen-aligned rows const int FogGridSizeZ = 64; // depth slices (logarithmic) // Depth distribution: near=dense slices, far=sparse // Slice 0 = near plane (~0.5m) // Slice 63 = VolumetricFogDistance (~2000m by default) // Voxel world size at slice z: // depth = exp(z / FogGridSizeZ * log(FarDist/NearDist)) * NearDist
The froxel grid is temporally reprojected each frame — previous frame's voxels are reprojeced using camera motion and blended with the current frame. This gives the appearance of high quality (low noise) fog with very few samples per voxel per frame.
Froxel 网格每帧被时域重投影——上一帧的体素使用相机运动重投影并与当前帧混合。 这使得每体素每帧极少样本就能呈现高质量(低噪声)的雾效果。
Local Fog Volumes — Bounded Volumetric Regions局部雾体积 — 有界体积区域
Local Fog Volumes (LocalFogVolumeRendering.h/.cpp) allow placing
bounded fog in specific world regions — useful for smoke, magic spells, swamp mist, or any effect
requiring localized volumetric density. A Local Fog Volume actor defines a sphere or box region with
its own density and material, injected into the main froxel grid during the volumetric fog pipeline.
局部雾体积(LocalFogVolumeRendering.h/.cpp)允许在特定世界区域放置有界的雾——
对烟雾、魔法法术、沼泽迷雾或任何需要局部体积密度的效果都很有用。
局部雾体积 Actor 定义具有自己密度和材质的球形或盒形区域,
在体积雾管线期间被注入主 Froxel 网格。
Volumetric Clouds — Real-Time Ray-Marched Cloud Layer体积云 — 实时光线步进云层
Volumetric Clouds use a full ray-marching approach through a user-defined cloud density field (typically computed via a Material). The cloud layer exists at a configurable altitude range (default 6–12km). Each view ray is marched through this altitude range, accumulating scattering and absorption from the cloud density material.
体积云通过用户定义的云密度场(通常通过材质计算)使用完整的光线步进方法。 云层存在于可配置的高度范围内(默认 6–12km)。 每条视线光线步进穿过这个高度范围,从云密度材质累积散射和吸收。
Cloud Material Architecture云材质架构
// Volumetric Cloud material (special domain: "Volume" in Material Editor) // The material outputs Extinction (density) — not color directly // Inputs available inside a cloud material shader: float3 WorldPos; // current ray position being evaluated float ViewSampleMipBias;// mip bias for noise textures (use for LOD) // Example cloud density shader logic: // 1. Basic layered noise (Worley + Perlin) float BaseShape = Texture3DSampleLevel(CloudBaseShape, UV * 0.5, MipBias).r; float Detail = Texture3DSampleLevel(CloudDetail, UV * 2.0, MipBias).r; // 2. Height gradient (clouds thin at base and top) float HeightFrac = saturate((WorldPos.z - CloudBaseAlt) / CloudLayerThickness); float HeightGrad = saturate(remap(HeightFrac, 0.0, 0.1, 0, 1)) // ramp up * saturate(remap(HeightFrac, 0.3, 1.0, 1, 0)); // ramp down // 3. Weather map (coverage, precipitation) float Coverage = WeatherTexture.Sample(Sampler, WorldPos.xy / 100000.0).r; // 4. Final density float Density = max(0, (BaseShape - (1 - Coverage)) * Detail) * HeightGrad; // Output to Extinction pin (controls how opaque the cloud is) return Density * ExtinctionScale;
Clouds render at quarter resolution by default and use temporal upscaling (reprojection from previous frames) to reach full resolution. Direct sunlight on clouds uses a multi-scattering approximation: a few "pseudo-scattering" cone samples to simulate light bouncing inside the cloud mass (producing the characteristic silver lining).
云默认以四分之一分辨率渲染,并使用时域升采样 (从前几帧重投影)达到全分辨率。云上的直射阳光使用多散射近似: 几个"伪散射"锥形样本来模拟光线在云团内的反弹(产生特有的银边效果)。
Sky Atmosphere — Bruneton Physically-Based Sky天空大气 — Bruneton 基于物理的天空
The Sky Atmosphere component uses the Bruneton (2008/2017) atmospheric scattering model, which accurately simulates Rayleigh scattering (molecules — blue sky) and Mie scattering (aerosols/dust — white haze near horizon). Unlike a simple sky texture, it responds physically to sun elevation: correct red sunrise/sunset, accurate zenith-to-horizon color gradient.
Sky Atmosphere 组件使用 Bruneton(2008/2017)大气散射模型, 精确模拟瑞利散射(分子——蓝天)和 Mie 散射(气溶胶/尘埃——地平线附近的白雾)。 与简单的天空纹理不同,它物理响应太阳高度角:正确的红色日出/日落,精确的天顶到地平线颜色渐变。
LUT-Based Precomputation基于 LUT 的预计算
Sky Atmosphere also generates the Aerial Perspective pass: a 3D LUT (camera frustum-aligned) that contains the accumulated inscattering and transmittance along view rays to distant objects. This makes mountains and distant geometry correctly "disappear" into atmospheric haze — physically accurate, no artist intervention needed.
天空大气还生成空中透视通道:一个 3D LUT(与相机视锥体对齐), 包含沿视线光线到远处物体的累积内散射和透射率。 这使山脉和远处几何体正确地"消失"在大气霾中——物理精确,无需美术人员干预。
How the Systems Interact系统如何相互作用
| System系统 | Range范围 | Uses Sky Atmosphere?使用天空大气? | Rendered After Opaque?在不透明后渲染? |
|---|---|---|---|
| Exponential Height Fog | Unlimited无限 | Can sample SkyAtmosphere color for fog tint可采样天空大气颜色用于雾色调 | Yes |
| Volumetric Fog | Near camera (~2km)相机附近(约 2km) | Inherits lighting from all scene lights继承所有场景灯光的光照 | Yes |
| Volumetric Clouds | Planetary (6–20km)行星级(6–20km) | Receives inscattering from Sky Atmosphere从天空大气接收内散射 | Before translucency在半透明之前 |
| Sky Atmosphere | Planetary (100km+)行星级(100km+) | N/A (is the sky) | Background (behind everything)背景(在所有物体后面) |
Performance Tuning性能调优
| CVar / Setting | Effect效果 |
|---|---|
| r.VolumetricFog | 0=disable, 1=enable. Most expensive single atmosphere feature (~2–5ms).0=禁用,1=启用。最昂贵的单一大气特性(约 2–5ms)。 |
| r.VolumetricFog.GridPixelSize | Froxel tile size in pixels. Default=8. Increase to 16 for 4× speedup (lower quality).Froxel 瓦片像素大小。默认=8。增到 16 可加速 4×(质量降低)。 |
| r.VolumetricFog.GridSizeZ | Number of depth slices. Default=64. Reduce to 32 for 2× speedup.深度切片数。默认=64。减少到 32 可加速 2×。 |
| r.VolumetricFog.Distance | Max fog distance. Reduce for performance (less volume to integrate).最大雾距离。减小以提高性能(更少体积需要积分)。 |
| r.Cloud.ShadowReflectionCapture | 0=disable cloud shadows in reflections (major performance saving)0=禁用反射中的云阴影(显著性能节省) |
| r.VolumetricCloud.RenderResolutionFraction | Default=0.25 (quarter res). Can set to 0.5 for better quality at cost.默认=0.25(四分之一分辨率)。可设为 0.5 以提高质量但增加成本。 |
| r.SkyAtmosphere.AerialPerspective.StartDepth | Distance before aerial perspective kicks in (default ~100m)空中透视开始生效的距离(默认约 100m) |
Source Navigation源码导航
- FogRendering.h/.cppExponential height fog: analytical formula, apply to scene指数高度雾:解析公式,应用到场景
- VolumetricFog.h/.cpp3D froxel grid setup, light scattering compute, integration pass3D Froxel 网格设置、光散射计算、积分通道
- VolumetricFogVoxelization.cppFog material injection: voxelize material density into the froxel grid雾材质注入:将材质密度体素化到 Froxel 网格
- VolumetricFogLightFunction.cppLight function evaluation inside the fog volume雾体积内的灯光函数计算
- LocalFogVolumeRendering.h/.cppBounded fog volumes: actor-placed fog regions injected into froxel grid有界雾体积:Actor 放置的雾区域,注入到 Froxel 网格
- VolumetricCloudRendering.h/.cppCloud ray-marching orchestrator, temporal reprojection, multi-scattering approx云光线步进协调器、时域重投影、多散射近似
- SkyAtmosphereRendering.h/.cppBruneton LUT precompute, sky view LUT update, aerial perspective passBruneton LUT 预计算、天空视图 LUT 更新、空中透视通道
- Shaders/Private/SkyAtmosphereCommon.ushRayleigh + Mie phase functions, transmittance/inscattering LUT sampling瑞利 + Mie 相位函数,透射率/内散射 LUT 采样
- Shaders/Private/VolumetricFog.usfFroxel light scattering compute shaderFroxel 光散射计算 Shader