3d游戏开发特性名词_Volumetric Fog Atmospheric Fog

与 大气散射[https://www.jianshu.com/p/dc8f2cd8a7f2] 相关

1. 相同的灵魂:物理公式

无论是大气散射(Atmospheric Scattering)还是体积雾(Volumetric Fog),它们底层都在算同一个积分公式:
也就是:

  • 光线射入介质(空气/雾)。
  • 光线被介质吸收(变暗)。
  • 光线被介质散射(发亮,形成光路)。
2. 不同的躯壳:工程实现的巨大差异

虽然公式一样,但应用场景的约束完全不同,导致了渲染管线走了两条路。
A. 大气散射 (Atmospheric Scattering)

  • 场景: 它是背景。距离无限远(从地面到太空)。
  • 光影: 它可以忽略遮挡(通常不计算云层或山体对大气的实时阴影,因为太远了)。
  • 优化手段:LUT (查找纹理)。
    • 因为这东西变化很慢(整个天空是渐变的),且它是“宏观”的,所以我们预计算成一张图,直接贴在无穷远的天球上。
    • 关键点: 它只处理“光和空气”,不处理“光和物体”。
      B. 体积雾 (Volumetric Fog)
  • 场景: 它是前景。距离很近(就在你相机前 0~100 米)。
  • 光影: 它必须计算遮挡。这是核心区别!
    • God Rays (体积光) 的本质: 当光线穿过雾气时,如果中间有一棵树挡住了光,雾气里必须出现一条黑色的“影子通道”。这就是 God Rays。
    • 大气散射通常不管这棵树,但体积雾必须管。
  • 优化手段:Frustum Voxel Grid (视锥体体素网格)。
    • LUT 没法用了,因为场景里的物体和灯光每帧都在变。
    • Raymarching(对每个像素暴力光线步进)太卡了。
    • 于是,工业界发明了“体素化”方案(见下文)。
3. Unity 中体积雾的底层:Frustum Voxel Grid

这是现代 3A 游戏(包括 Unity HDRP 和 Unreal Engine)实现体积雾和 God Rays 的标准技术。
它的原理非常巧妙:

  • 切蛋糕 (Voxelization):
    • 想象你的相机视锥体(Camera Frustum)是一个梯形的蛋糕。
    • 我们在低分辨率下(比如 160x90x64),把这个空间切成无数个小方块(Voxels/Froxis)。注意,这里的 Z 轴是沿着相机深度的。
  • 计算光照 (Compute Shader):
    • 对于每一个小方块,我们在 Compute Shader 里计算:
      • 这个方块里有雾吗?(Density)
      • 这个方块被光照到了吗?(采样 Shadow Map) —— 这就是 God Rays 产生的地方! 如果 Shadow Map 说这个点是黑的,那这个方块就不亮。
    • 结果存入一张 3D Texture (3D 纹理)。
  • 光线累积 (Raymarching the 3D Texture):
    • 沿着视线方向,把这些小方块的亮度和透明度累加起来(积分),生成一张最终的体积光纹理。
  • 混合 (Upsampling):
    • 把这张低分辨率的体积光纹理,拉伸放大,覆盖到屏幕上,和场景物体混合。
4. 你的困惑:FogVolume 和 VolumetricLight 是什么?

在 Unity (特别是 HDRP) 中,这些组件就是为了控制上面提到的那个 Voxel Grid。

  • Volumetric Fog (Global):
    • 设置整个场景的基础雾浓度。它填充了所有的 Voxels。
  • Fog Volume (Local):
    • 这是一个局部覆盖。比如你走进一个沼泽,这里有一个 Box Collider。
    • Unity 会判断:如果某个 Voxel 在这个 Box 范围内,就人为增加这个 Voxel 的密度数据。
    • 这就像是在那张 3D 纹理里“画”了一团墨水。
  • Volumetric Light (Light Component):
    • 这是告诉渲染器:计算 Voxel 光照时,请把这盏灯也算进去。
    • 开启 Volumetric Shadows:计算 Voxel 时强制采样 Shadow Map。有了这个,光线被物体遮挡后,雾气里才会出现“光柱” (God Rays)。
5. 总结:如果我在 Unity 里都要用,会有冲突吗?

不会,它们通常是分层叠加的:

  • 最远处: Atmospheric Scattering (天空盒) 负责渲染蓝天、夕阳背景。这是底色。
  • 近处: Volumetric Fog (体积雾) 负责渲染你身边的空气感、路灯的光晕、树林里的耶酥光。这是叠加层。

所以,你现在的理解完全打通了:大气散射是大自然的宏观背景,体积雾是场景里的微观光影,两者物理同源,但工程分家。


unity URP

这是一个非常关键的问题,因为 Unity 在 URP (Universal Render Pipeline) 和 HDRP 的策略上长期存在巨大差异。
答案取决于你使用的 Unity 版本:
情况 A:Unity 6 (2023.3+) —— 终于有了!
在最新的 Unity 6 Preview (以及 URP 17+) 中,Unity 终于给 URP 加入了原生的 Volumetric Fog (体积雾)。

  • 它的原理:
    它确实使用了类似 HDRP 的技术(基于 3D 纹理/Voxel 的 Raymarching),但为了适配中低端设备(手机、Switch),它做了一些简化和优化。
  • 怎么开启:
    • 在 URP Asset 设置里,找到 Quality -> Volumetric Fog 并勾选。
    • 在场景里的 Global Volume 组件中,添加 Override -> Fog。
    • 把 Fog Mode 改为 Volumetric。
  • 能实现 God Rays 吗?
    能。它会结合 Shadow Map 计算光柱。
    情况 B:Unity 2022 LTS 及更早版本 —— 默认没有
    如果你还在用目前主流的 Unity 2020, 2021, 或 2022 LTS,答案是 No。
    默认的 URP 只有 基础雾 (Basic Fog)。
  • 它是什么: 仅仅是根据像素的深度(Depth),把远处物体的颜色混合成灰色。
  • 它不是什么: 它完全不懂光照。光线穿过它不会变亮,物体遮挡光线也不会产生“上帝之光” (God Rays)。它只是一个全屏滤镜。
    那在老版本 URP 里怎么实现 God Rays?
    既然官方没给,在 URP 中实现体积光通常有两条路:
1. 方案一:屏幕空间散射 (Screen Space God Rays) — 性能最好,效果一般(TODO,不懂)

这是一种“假”体积光,也是手游最常用的方案。

  • 原理:
    • 渲染一张只有太阳和高亮物体的图(把遮挡物扣黑)。
    • 对这张图进行径向模糊 (Radial Blur)。
    • 把模糊后的结果叠加回屏幕。
  • 优点: 极快,手机随便跑。
  • 缺点: 只有当你看着太阳时才有光柱。如果你转头,光柱就消失了(因为它只存在于屏幕空间)。
  • 实现: 以前需要自己写 ScriptableRendererFeature,现在 Asset Store 有很多免费的(如 Occulusion Shafts)。


    image.png
2. 方案二:基于 Mesh 的假光柱 — 这种最古老
  • 原理: 美术做一个圆锥体的模型,贴一个半透明的材质,插在窗户或路灯下。
  • 优点: 极度省性能,完全可控。
  • 缺点: 穿帮严重,人走进去不会有真实的体积感,只是个透明片。
3. 方案三:使用插件 (Asset Store) — 最推荐

由于 URP 官方长期缺席,Asset Store 里的插件已经进化得非常完美。它们通过自定义 Render Feature 实现了真正的 Frustum Voxel Grid 体积雾。
最著名的两款(几乎是 URP 项目标配):

  • Volumetric Fog & Mist 2 (Cronos): 性能优化极好,支持手机,效果接近 HDRP。
  • Aura 2 / Aura 3: 效果极度炸裂,但比较吃性能,适合 PC/主机版 URP 游戏。
    总结:URP 到底用不用那个“Voxel Grid”技术?
  • Unity 2022 及以前: 默认不用。默认只有深度雾。
  • Unity 6+: 默认用了(简化版)。
  • 插件(如 Volumetric Fog 2): 用了。它们手动实现了那套技术。

Atmospheric Fog 大气雾

与Volumetric Fog 不是一回事,但在视觉目标上有重叠。
你可以把 Atmospheric Fog (大气雾) 看作是“平面的、基于距离的着色欺骗”,而把 Volumetric Fog (体积雾) 看作是“真实的、具有物理特性的空间介质”。

1. Atmospheric Fog vs. Volumetric Fog
特性 Atmospheric Fog (大气雾/常规模拟) Volumetric Fog (体积雾)
实现原理 基于深度缓冲区(Z-Buffer)。根据物体离相机的距离,直接在颜色上插值。 基于体素(Voxel)或参与介质。模拟光线在空气中被粒子散射的过程。
空间感 均匀的。无论你怎么动,雾的密度只随距离变化。 3D空间的。你可以看到雾团、光柱(丁达尔效应)。
光照交互 很难受光照影响,通常只是简单的颜色叠加。 与光影完美融合。阴影会遮挡光路产生“光轴”。
性能开销 极低(几乎免费)。 较高(涉及 3D 纹理和射线步进 Raymarching)。
2. Unity URP 中有内置吗?

关于 Atmospheric Fog,情况比较微妙:

  • 基础距离雾 (Distance Fog): 有内置。
    在 URP 的 Lighting 窗口 -> Environment 选项卡下,你可以开启 Fog。它支持 Linear、Exponential 和 Exponential Squared 三种模式。这是最基础的大气模拟。
  • 物理大气散射 (Atmospheric Scattering): 部分内置。
    在 URP 的 Volume 系统中,有一个 Physically Based Sky。它能模拟天空因大气散射产生的颜色变化,但它更多是针对“天空盒”,而不是针对场景深度中的“雾气”。
  • 体积雾 (Volumetric Fog): 官方没有原生内置。
    这是 URP 经常被开发者吐槽的一点。相比之下,Unity 的 HDRP 是原生内置高质量体积雾的。
3. 如果没有,该如何实现?

如果你在 URP 中需要实现更高级的大气雾或体积雾,通常有以下几种方案:

A. 开启内置基础雾(最简单)
  • 打开 Window > Rendering > Lighting。
  • 在 Environment 标签页勾选 Fog。
  • 确保你的 Shader 包含 multi_compile_fog 变体(URP 官方 Shader 均已支持)。
B. 使用 Shader Graph 自定义(大气雾进阶)

如果你想要那种“高度雾”(低处浓、高处薄),你可以用 Shader Graph 编写一个全局后处理效果:

  • 利用 Position 节点的 World Space Y 轴分量。
  • 公式参考:FogDensity = e^{-Height \cdot Density}。
  • 通过 Renderer Feature 将其注入到渲染管线中。
C. 使用第三方插件(实现体积雾的最佳途径)

由于从零开发高性能的体积雾(基于 GPU 3D LUT 或 Froxel)门槛较高,社区通常推荐成熟的插件:

  • Buto: 专门为 URP 设计,视觉效果极佳。
  • Aura 2: 经典的体积光/雾解决方案。
  • Enviro / Weather Maker: 这种全天候系统插件自带了高质量的大气和体积雾功能。
D. 手动实现简单的体积光(Fake 方案)

如果你只需要一束光照下来的感觉,可以使用 Radial Blur (径向模糊) 后处理,或者使用简单的 Mesh Beam (面片光柱) 配上软粒子 Shader。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容