中EN
概念页

雾与简易体积光照

Fog & Simple Volumetric Lighting

更新于 2026-10-16 约 6 分钟体积渲染深度雾高度雾局部雾光柱水下

这类"老派"技巧依赖经验模型,但至今仍然好用:深度雾、高度雾和局部雾体积用透射率混合雾色;光柱可用拉伸的面向相机粒子、单次散射的解析积分、平面切片,或屏幕空间径向模糊实现(RTR4 14.2 节)。

雾的作用

增加真实感和氛围;帮助判断距离的重要深度线索(《战场 1》用深度雾表现场景尺度,用高度雾表现从山谷升起的建筑);可作为遮挡剔除——完全没入雾中的远处物体可以跳过不画。

深度雾

用 f∈[0,1]f\in[0,1] 表示透射率(f=0.1f=0.1 表示背景可见 10%),表面色 ci\mathbf{c}_i、雾色 cf\mathbf{c}_f:

c=f ci+(1−f) cf\mathbf{c}=f\,\mathbf{c}_i+(1-f)\,\mathbf{c}_f

形式公式说明
线性f=zend−zszend−zstartf=\dfrac{z_{end}-z_s}{z_{end}-z_{start}}zstartz_{start}、zendz_{end} 为雾开始与完全浓雾处,zsz_s 为到表面的线性深度
指数f=e−dfzsf=e^{-d_fz_s}符合 Beer-Lambert 定律,dfd_f 控制浓度,物理上更准确
  • 这是旧版 OpenGL/DirectX 硬件雾的接口,移动设备等简单场合仍值得用。现代游戏多用后处理:深度缓冲是非线性的,可用逆投影矩阵还原线性深度,再在全屏 pass 中实现高度雾、水下着色等。
  • 雾色可以是单色、按视线采样的立方体贴图,甚至带逐像素相位函数的大气散射结果;深度雾与高度雾可相乘 f=fdfhf=f_df_h 共存。

高度雾与局部雾

  • 高度雾:一块有参数化高度和厚度的介质层,按视线穿过它的距离计算密度和散射;Wenzel 给出层内介质指数衰减时 ff 的闭式解,边缘过渡平滑。
  • 局部雾(洞穴、墓地):用椭球或盒子,按包围盒从后往前渲染,像素着色器求视线与形状的前交点 dfd_f 和后交点 dbd_b,体积深度 d=max⁡(0,min⁡(zs,db)−df)d=\max(0,\min(z_s,d_b)-d_f)(zsz_s 为最近不透明表面线性深度),由此得 TrT_r,覆盖率 α=1−Tr\alpha=1-T_r,叠加散射光 α cf\alpha\,\mathbf{c}_f。
  • 任意网格形状:Oat 与 Scheuermann 单 pass 求最近入点和最远出点——一个通道存表面距离 dsd_s,另一个存 1−ds1-d_s,混合模式取最小值,渲染后第一通道是 dfd_f、第二通道编码了 1−db1-d_b。

水

水也是参与介质。近岸海水每米透射率约 (0.3,0.73,0.63)(0.3,0.73,0.63),可反推 σt=(1.2,0.31,0.46)\sigma_t=(1.2,0.31,0.46)。用不透明面画深色水时,相机在水下开启雾逻辑、水上关闭。Wenzel 的更好做法:水下时积分到碰到实体或水面为止;水上时只积分水面到海底实体之间的距离。

简易体积光照

  • 网格溅射:窗户、密林、聚光灯的光柱用带纹理的面向相机粒子,沿光柱方向拉伸并保持面向相机(圆柱约束)。缺点:大量透明网格累加耗带宽,面向相机的四边形有时会露馅。
  • 解析单次散射:假设均匀介质和各向同性相位函数,可闭式积分沿路径的散射光(含正确透射率),作为后处理或用于每个带深度的粒子。书中给出 GLSL 片段(参数为光线起点、单位方向、光源位置和积分距离),核心是一个反正切表达式:
float inScattering(vec3 rayStart, vec3 rayDir, vec3 lightPos, float rayDistance) {
    vec3 q = rayStart - lightPos;
    float b = dot(rayDir, q);
    float c = dot(q, q);
    float s = 1.0f / sqrt(c - b*b);
    float x = s * rayDistance;
    float y = s * b;
    return s * atan((x) / (1.0 + (x + y) * y));
}

Sun 等额外考虑 σs\sigma_s,以及光在到达朗伯/Phong 表面前走了非直线路径对其漫反射和高光的影响;考虑透射率和相位函数的版本 ALU 更重。这些模型都不能处理深度图阴影或非均匀介质。

  • 泛光近似:模糊帧缓冲并把一小部分加回,亮物体周围就会"漏光",在短距离、无遮挡散射的环境里效果不错。
  • 平面切片:Dobashi 等用一系列垂直视线的平面从后往前采样体积渲染大尺度大气效果;Mitchell 用同法做聚光灯光柱,并用阴影贴图让不透明物体投下体积阴影。
  • 屏幕空间光柱(Mitchell、Rohleder 与 Jamrozik):在清黑的缓冲中于远平面太阳周围画一个假的亮物体,深度测试只保留未遮挡像素;再做以太阳为中心的方向模糊把亮度向外"漏"(可分离两遍各 nn 样本,得到 n2n^2 样本的效果);最后加到场景上。高效、视觉收益大,缺点是只有屏幕上可见的光源能产生光柱。

GPU Gems 的视角:体积光散射后处理 / 耶稣光(GPU Gems 3 第 13 章)

来源:Kenny Mitchell《Volumetric Light Scattering as a Post-Process》;摘录 Chapter 13. Volumetric Light Scattering as a Post-Process — Kenny Mitchell。对应上文「屏幕空间光柱」路线,把 Hoffman–Preetham 昼光解析模型接到遮挡估计上。

思路:在屏幕空间沿像素到光源的射线累加采样,用「击中发光区 vs 击中遮挡物」的比例估计 D(θ)D(\theta),再对源照明做衰减。实现就是带 Weight / Decay / Density / Exposure 的径向模糊;衰减指数让光柱离开光源平滑收束。半透明遮挡无需特判;多光源就多趟加法合成。

纹理对比会拉出假条纹,可用遮挡预通道(遮挡物画成黑、无纹理)再合成,或模板标记天空,或靠雾/大气透视压对比。局限:近景物体前可能出现「本该被挡住的背景光柱」(有时被看成镜头散射);遮挡物出画会闪(可渲染超扫描区域);光源近乎垂直视线时屏幕位置趋于无穷(钳制或淡出)。Shader Model 3 可单 pass 循环;更老硬件用多遍帧缓冲加法。这与 froxel 体积光照不同:几乎零场景设置,但不是物理厚度积分。

  1. realtime_rendering_4ed.pdf 第 14 章 Volumetric and Translucency Rendering
  2. Chapter 13. Volumetric Light Scattering as a Post-Process — Kenny Mitchell
  3. developer.nvidia.com/gpugems/gpugems3/part-ii-light-and-shadows/chapter-13-volumetric-light-scattering-post-process

相关页面

图形学泛光与镜头光晕Bloom & Lens Flare镜头光晕是光经镜头系统或眼睛的间接反射等非预期路径产生的现象;泛光 (bloom) 是镜头和眼睛中的散射在亮光周围形成辉光、并降低其他地方对比度。显示器亮度有限,加入这些眩光效果可以暗示更高的亮度。实现上,光晕常用随光源位置变化的公告板或对亮部做图像处理,泛光则是"提取亮部 → 降采样模糊 → 加回原图"(RTR4 12.3 节)。图形学天空与云渲染Sky & Cloud Rendering天空颜色和空气透视来自空气分子的瑞利散射,太阳周围的光晕来自近地大颗粒的米氏散射。实时方案有解析拟合模型和基于预计算透射率/散射查找表的物理模型;云则从全景贴图、粒子发展到用程序化噪声构建、光线步进的参与介质层,并以倍频程近似多次散射(RTR4 14.4 节)。图形学图像处理与后处理Image Processing & Post-Processing后处理是在渲染出图像后再用 GPU 对其做图像处理:把离屏缓冲当纹理,用全屏 pass 让像素着色器(或计算着色器)对每个像素采样邻域并加权求和。核心技巧包括可分离滤波、利用双线性插值减少采样、降采样、以及借助深度/法线保持边缘的(联合)双边滤波(RTR4 12.1 节)。游戏数学投影矩阵Projection Matrix投影矩阵把视景体变换到规范视体(OpenGL 为 [-1,1]^3,DirectX 的 z 为 [0,1]),在那里裁剪更高效。正交投影保持平行线平行、物体大小与距离无关;透视投影让远处变小,产生的深度与观察深度成反比,近平面位置和"反向 z"决定深度精度。图形学公告板Billboarding公告板是根据视线方向调整朝向的带纹理矩形。配合 alpha 纹理和动画,它能表现草、烟、火、雾、爆炸、能量护盾、尾迹、云等没有光滑实体表面的现象。各类公告板的区别只在于固定哪个向量(法线或上方向);软粒子、球形公告板解决与实体相交和穿过近平面的问题,轴向公告板用于树木、激光等柱对称物体(RTR4 13.6–13.6.3 节)。图形学剔除技术Culling Techniques剔除 (culling) 是在渲染前尽快去掉对最终图像没有贡献的部分。本页讲几何类剔除:背面剔除(含成簇背面剔除与法线锥)、视锥剔除(层次化、平面掩码)、室内场景的入口剔除,以及牺牲质量换速度的细节剔除和小三角形剔除。更复杂的遮挡剔除见 遮挡剔除。图形学半透明表面与折射Translucent Surfaces & Refraction玻璃、水、红酒等高吸收、低散射材质:覆盖率 \alpha 与透射率 Tr 是两回事——前者遮挡背景,后者按波长过滤背景。厚度变化时按 Beer-Lambert 定律计算彩色透射;折射可用环境贴图或屏幕空间扰动近似,粗糙表面按粗糙度模糊背景;焦散则用动画贴图、光线光栅化或图像空间光子溅射近似(RTR4 14.5 节)。游戏开发 · UE5天空大气与体积云Sky Atmosphere & Volumetric Clouds天空大气 (Sky Atmosphere) 组件是基于物理的天空与大气渲染:模拟瑞利散射 (Rayleigh)、米氏散射 (Mie) 和臭氧吸收,天色随太阳高度变化,并提供带行星曲率的空气透视,可以从地面平滑过渡到外太空。体积云 (Volumetric Cloud) 组件用材质驱动的三维体积纹理做光线步进,多次散射用若干「八度」近似,云的阴影可以用光线步进或 Beer 阴影贴图。游戏美术日光与大气透视Daylight & Aerial Perspective搭建动机与 cheat 见 Birn 环境与建筑布光(第 3 版 Ch4);本页偏 Dinur 真实感/大气侧。 Dinur Ch6:太阳因极远而在地球上近似平行光;大气通过吸收/反射、Rayleigh 与 Mie 散射改写日光颜色与天空;大气透视 (aerial perspective) 是距离感的根基。本页给户外 Look Dev 检查项;体积散射算法与 UE 天空系统见图形学/UE5 链出页。图形学参与介质与体积散射Participating Media & Volumetric Scattering参与介质是充满粒子、通过吸收和散射参与光传输的体积,如空气、水、雾、烟、云;皮肤、蜡等致密材质也有强烈散射——"一切都是散射"。实时渲染主要考虑单次散射:沿视线积分透射率衰减后的内散射光,内散射由相位函数和对光源的可见性(不透明阴影 × 体积阴影)决定。通用实时方案把介质材质和散射结果体素化到相机视锥体素 (froxel) 中逐片累积(RTR4 14.1、14.3、14.8 节)。游戏美术Doom 3 体积光晕Doom 3 Volumetric GlowGAT 33:Doom 3 灯具周围的「体积」光晕——美术只放简单多边形并挂材质,运行时用(疑似顶点色)网格按视角折叠展开形成光圈;仅在正对光源时绘制并随角度淡出。偏 glare(看不见光源则消失),而非持续 haze。

输入关键词开始搜索

滚轮或双指缩放 · 拖动平移 · 双击放大 / 还原