文章目录
- 三、大气Atmosphere
- 3.1 大气散射理论
- 3.1.1 Analytic Atmosphere Appearance Modeling(经验模型)
- 3.1.2 Participating Media参与介质
- 3.1.3 辐射传递方程RTE(Radiative Transfer Equation)
- 3.1.4 体积渲染公式VRE(Volume Rendering Equation)
- 3.2 大气物理学(Real Physics in Atmosphere)
- 3.2.1 Rayleigh Scattering(瑞利散射)
- 3.2.2 Mie scattering(米氏散射)
- 3.2.3 Variant Air Molecules Absorption(光的吸收)
- 3.2.4 single Scattering vs Multiple Scattering(单次散射 vs 多次散射)
- 3.2 实时大气渲染
- 3.2.1 PreComputed Atmospheric Scattering
- 3.2.2 (预计算方法简化版)
- 四,云的渲染
- 4.1 Volumetric Cloud Modeling
- 4.2 Rendering Cloud by Ray Marching
- Q&A
天空由大气和云组成的,先放一张课程开始的美图
三、大气Atmosphere
3.1 大气散射理论
3.1.1 Analytic Atmosphere Appearance Modeling(经验模型)
类似光线追踪,大气渲染也有类似渲染公式,在实际处理中也有类似 Blinn-Phong的拟合模型。关键参数是view到天顶的角度和到太阳的角度,给出两个参数就可以通过以上公式算出一个解析解,就可以得到颜色
- 优点:计算简单且有效
- 缺点:只有地表视角;参数写死,得出的解也是固定的,真实情况的下雨等情况不能覆盖
3.1.2 Participating Media参与介质
指构成大气中各种透明又不透明的粒子,主要有各种气体和气溶胶介质
- 光和大气介质的交互:
- 光被吸收(Absorption)
- 光被散射(Out-scattering)
- 自发光(Emission)
- 周边被点亮的气体,散射过来照亮自己(In-scattering)
3.1.3 辐射传递方程RTE(Radiative Transfer Equation)
- 这四种合到一起就形成了辐射传递方程RTE(Radiative Transfer Equation)----知道概念,不用记,后续全都预计算
(σ𝑎:吸收系数、σ𝑠:散射系数)
3.1.4 体积渲染公式VRE(Volume Rendering Equation)
- RTE表达的是一个梯度,对RTE积分,就得到体积渲染公式VRE(Volume Rendering Equation)
其中有2个主要变量:
- Transmittance(通透度):假设我在M点放一个东西,到p点还能剩下多少(路径积分的结果)
- Scattering Function:路径叠加到的沿途散射过来的光,打到相机的部分
3.2 大气物理学(Real Physics in Atmosphere)
大气主要有两个参数者:
- 太阳:太阳由各种不同的波长的光组成
- 大气:主要有两类----气体(小于太阳波长)和气溶胶(接近太阳波长)
3.2.1 Rayleigh Scattering(瑞利散射)
当空气中介质尺寸远小于光的波长的时候(气体):
- 空气中的光是四面八方均匀散射,不太具有方向性
- 对于越短的波长(蓝紫光),它散射的越远,对越长的波长(红光),散射的越近
- Rayleigh Scattering Equation:
λ:光的波长,因此 1 λ 4 \frac{1}{λ^4} λ41也说明波长越短,散射越多
θ:入射光和散射光的夹角(旋转不变)
h:海拔高度
ρ:大气密度,在海平面上等于1,随着高度上升呈指数递减
n:空气折射率
可以看到,在给定海拔高度和空气密度时,散射方向只与face function(形状函数)也就是 1 + c o s 2 θ 1+cos^2θ 1+cos2θ有关,参数只有一个θ角。
这就可以解释
为什么天空是蓝色----波长短散射多;
为什么晚霞是红色----入射角小蓝色散射出视角了,剩下红色;
3.2.2 Mie scattering(米氏散射)
当空气中介质尺寸接近或大于波长时(气溶胶):
- 散射有一定方向性,更多散射再光的传播方向
- 但对波长不敏感,同等的散射所有波长
- 米氏散射方程(Mie Scattering Equation)
方程引入了一个Geometry Parameter:g
- g = 0时,就变成了瑞利散射的形状
- g > 0 时,更接近于图中章鱼形状
- g < 0 时,会往相反的方向散射得更多(g一般大于0)
日常生活中的雾就是气溶胶,表现为无差别散射,所以是白色的;而傍晚的光晕是有方向性的米氏散射,所以有个halo在太阳附近(雨天的路灯也一样)
3.2.3 Variant Air Molecules Absorption(光的吸收)
空气中的臭氧(O3)和甲烷(CH4)能够吸收长波的光,比如臭氧吸收红橙黄光,甲烷吸收红光。(海王星为什么是蓝色—其表面的大量甲烷吸收了红光,显现蓝色)
我们计算也要考虑这种光的吸收,但实际计算过程中会假设这些气体是均匀分布在整个大气中的(实际上并不是,比如臭氧集中在大气上层)
3.2.4 single Scattering vs Multiple Scattering(单次散射 vs 多次散射)
- 单次散射:眼睛看到一个点,看到的是该方向所有被太阳光照亮后,散射到我眼睛这个方向的能量和的Transmittance积分
- 多次散射:其他物体散射的光照亮我实现方向的粒子,相当于光追的多Bounce-----现代3A游戏必须面对的重要问题
「多散射和GI的区别:GI是光照射到了一个面,然后反射到其他地方最后照射的你的眼睛,而多散射则作用于空间中连续不断地空气」
3.2 实时大气渲染
Ray Marching 我们都知道是沿着视线路径把结果一步一步积分的方法
3.2.1 PreComputed Atmospheric Scattering
- Transmittance LUT
这里也可以借助预计算的思想,先用Ray Marching去计算给定点的最终的单次散射的Transmittance,并把最终积分结果存放到 LUT中,通过两个参数:θ:视线和天顶(y+)的夹角;h:海拔高度,就可以获得Transmittance。
并且,如果视点到B的通透度:𝑇(𝑋𝑣−>𝐵),中间点m到B的通透度:𝑇(𝑋𝑚−>𝐵),那么视点到m的通透度为:
T
(
X
v
−
>
B
)
T
(
X
m
−
>
B
)
\frac{T(X_v->B)}{T(X_m->B)}
T(Xm−>B)T(Xv−>B)
有了这个公式之后,单次散射公式就可以表示为:
- Single Scattering LUT
这里最重要的是一种参数化思想,将三维角表达为3个角度,做成一组LUT图,叫Single Scattering LUT(4维表),来表示站在所有点在所有太阳角度下看任何方向的一次散射的预计算结果,将其保存在个3Dtexture array里(其实应该用3D texture,方便中间高度采样)。
其中:
η:视点到太阳的方向和天顶夹角,cos值为μs
θ:视线和天顶夹角,cos值为μ
φ:视点到太阳的方向与视线夹角,cos值为v
h:视点海拔高度
- Multiple Scattering LUT
进一步的,通过通透度LUT图和单次散射LUT图,就可以计算出二次、三次以及更多次散射的LUT表(一般3、4次就够了),这些图与一次散射LUT图长得一模一样。
借用以上这些与计算图就可以在runtime下达到一个很好效果的实时计算。
- 该预计算方法缺点:
- 预计算耗费很大,多次散射的迭代计算成本高,其次是在移动端没法用。(即使在PC上用computeShade需要几毫秒甚至一秒,但可能分到很多帧去完成)。
- 没法处理动态环境调整,比如晴天到阴雨的过渡,需要有个平滑的过渡,因此每帧的表都要计算,消耗过大;同时艺术家编辑时调节参数也不方便。
- Runtime实时处理时需要做很多逐像素的高维LUT表的插值(为了效率经常要下采样)。
3.2.2 (预计算方法简化版)
前沿的游戏行业简化计算方法,UE正在用的:A Scalable and Production Ready Sky and Atmosphere Rendering Technique,pdf连接
他假设:散射是低频的,对于空气中的分子的散射是各向同性的,因此光是均匀的,散射也是均匀的,每级散射直接按百分比衰减就行了,多次散射就变成了等比数列,介质多次散射的结果总和就变成了数列求和。???
这样一来就极大加快了速度,可以每一帧都进行计算了,那原方法LUT中的高度h参数就没有意义了,同时每帧都算的话,太阳顶角的参数也就不需要了,所以新方法的LUT表中只需要计算出观察方向的天顶角 θ 和一个水平方向环绕360度的夹角 ϕ(对应原来太阳到观察视角水平方向的夹角)即可,化四维为二维,见下图左。
如果再加上大气中沿着路径的透明度积分影响,那就再加上一个相机距离的参数,形成一个3Dtexture,见下右图。
这样一来,太阳月亮、下雨晴天等情况就都能表达了;只有在空气散射度特别高、雾很浓的情况下,会有比较大的偏差,甚至有色偏。并且效率非常高,支持移动端。
四,云的渲染
云的类型从低到高有层云、积雨云、高层云、高积云、、卷层云、卷积云等等。
早期实现云的方式有:
- Mesh-Based Clod Modeling:mesh硬做,大概模型+noise、腐蚀算法等实现,现在基本没人用了,效率低且不动态
- Billboard Cloud:用半透明插片模拟,虽然效率高,但效果差、云的种类有限
4.1 Volumetric Cloud Modeling
- 优点:云的形状真实、可以实现大尺寸的云、支持动态天气、支持动态体积光照和阴影
- 缺点:算法复杂,花费巨大(但因为效果好,现在3a游戏还是会用)
思路:Weather Texture(形状分布+0-1值表示的厚度) + 平移、扰动变形
- 这里的noise扰动对其真实性非常重要,比如Perlin Noise(棉絮状噪声)和Worley Noise(细胞结构状)等
- 具体实现:先利用低频把云的规则边缘模糊化,再加上一些高频来优化细节。
4.2 Rendering Cloud by Ray Marching
那做出来云之后如何进行渲染呢?Ray Marching
- 对每个屏幕像素做射线,看能不能打到云
- 在没打中云时采用较大的步长(云设定在固定高度)
- 打中云时采用非常小的步长
- 在打中的每一个点计算通透度以及散射(比大气散射计算更要简化,因为云通透度很低)
效果很好,不过计算还是比较贵,但是是现代游戏引擎的标配。
Q&A
- 本节课讲的地形四叉树管理与前边讲的GameObject的四叉树管理是否可以共用?
是的,完全共用
- 体积云的渲染是否比较耗时,怎么解决?
是的,虽然简化了很多,但计算还是不少,并且云的颜色还会受到大气影响,乱七八糟加起来还是很耗时。可以优化比如:Ray Marching时对屏幕像素进行下采样,只计算1/4像素;再加上DLSS辅助。
- 大气散射计算的终止条件是什么:多次散射计算3-4次