基于GPU预计算的大气层光效渲染
- 前言
- 大气物理模型
- 渲染方程及其实现
- 实验结果
- 参考文献
前言
本文叙述基于物理模型的大气层光效渲染,不仅考虑单重散射,而且也尝试实现多重散射的效果。主要参考论文为Eric Bruneton和Fabrice Neyret的《Precomputed Atmospheric Scattering》。博文如果错误,欢迎指出,非常感谢。此外,本文较多物理理论和数学推导,代码也比较多。
代码已放至本人的github上:https://github.com/ZeusYang/Atmosphere
大气物理模型
1、大气散射现象
大气散射是指,太阳光在射入大气层时,与大气中的空气分子或空气溶胶等发生相互作用,使得入射的光能以一定的规律在各个方向上进行重新分布的现象。太阳光在射入大气层时,遇到大气分子、尘埃、雨滴等颗粒后,都会发生散射现象。其中一部分的光能会被这些粒子吸收转化为热能,而另一部分光能则会以该粒子为中心,向四面八方扩散开来。所以,在经过了大气的散射作用之后,有部分太阳光将无法抵达地球表面。大气散射在自然界中是一种十分重要而又普遍存在的物理现象,人们平时用肉眼观察到的光很大一部分都是散射光。如果没有大气散射,那么只要不是太阳光直接照射到的位置,都将是完全黑暗的。
2、空气物理模型
空气中的介质颗粒根据其直径大小的不同可分为两种:直径远小于光线波长的空气微粒、与直径与光线波长相当的空气溶胶。由前者引起的散射我们称为Rayleigh散射,它是导致晴朗天空呈现蓝色的主要原因。由后者引起的散射我们称为Mie散射,它是导致阴霾的天空呈现灰色的原因,因为阴天的空气中存在大量与光波直径相当的水滴。
①Rayleigh散射:由空气中远小于波长的微粒(如空气分子)引起的散射称作瑞利散射。Rayleigh散射强度与光线波长的四次方成反比,这意味着白光中波长较短的颜色光(蓝色)会比波长较长的光(红色)有更强的散射强度,导致天空在白天偏向蓝色,而在黄昏偏向橙红色。 当日出或日落的时候,由于太阳的位置接近地平线,阳光斜射入大气,会在大气层中穿过很长的距离。在这个过程中,太阳光中的蓝色光几乎都会被散射殆尽无法抵达人眼,只剩下了波长较长的红色光,所以在太阳及其周围的天空都会呈现橘红色。
Rayleigh散射的散射系数可以使用如下公式计算:
β R ( θ ) = 2 π 2 ( n 2 − 1 ) 2 3 N λ 4 p R ( θ ) \beta_R(\theta)=\frac{2\pi^2(n^2-1)^2}{3N\lambda^4}p_R(\theta) βR(θ)=3Nλ42π2(n2−1)2pR(θ) (1)
其中 θ \theta θ是视线与太阳光线的夹角, N N N是大气分子密度, n n n是大气的折射率, λ \lambda λ是入射光的波长, p R ( θ ) p_R(\theta) pR(θ)是单位化的相位函数。由上可知,Rayleigh散射明显与波长的四次方成反比,在实现中我们可用一个RGB向量来表示,散射系数可表示为:
β R . r g b = ( 5.81 , 13.5 , 33.1 ) × 1 0 − 6 \beta_R.rgb=(5.81,13.5,33.1)\times10^{-6} βR.rgb=(5.81,13.5,33.1)×10−6 (2)
由于Rayleigh散射几乎是各向同性的,即光线会被粒子向各个方向均匀散射,其相位函数可以表示为:
p R ( θ ) = 3 16 π ( 1 + c o s 2 θ ) ) p_R(\theta)=\frac{3}{16\pi}(1+cos^2\theta)) pR(θ)=16π3(1+cos2θ)) (3)
相位函数描述了散射的方向特征,也就是在视线与光线夹角为 θ \theta θ的情况,在总共散射的光线中有多少被散射到视线方向上,可以理解为概率或者比例。
② Mie散射:在空气中直径与波长相当的微粒(如尘埃、雾滴等)所导致的散射现象称作Mie散射。与Rayleigh散射不同,Mie散射与波长无关,散射方向表现出明显的各向异性,光线会被粒子更多的向后方散射。而当阴雨天气时,空气中存在大量的水滴颗粒,Mie散射导致天空呈现灰白色。现今经常出现的雾霆天气,同样是因为空气中悬浮的大颗粒过多而导致的Mie散射现象。
由于Mie散射与波长无关,故可以用标量表示,Mie散射系数为:
β M . r g b = 2.0 × 1 0 − 5 \beta_M.rgb=2.0\times10^{-5} βM.rgb=2.0×10−5 (4)
Mie散射的方向是各向异性的,光线会被更多的向后方散射,其相位函数为:
p M ( θ ) = 1 4 π 3 ( 1 − g 2 ) 2 ( 2 + g 2 ) 1 + c o s 2 θ ( 1 + g 2 − 2 g c o s θ ) 3 2 p_M(\theta)=\frac{1}{4\pi}\frac{3(1-g^2)}{2(2+g^2)}\frac{1+cos^2\theta}{(1+g^2-2gcos\theta)^{\frac{3}{2}}} pM(θ)=4π12(2+g2)3(1−g2)(1+g2−2gcosθ)231+cos2θ (5)
在公式(5)中, θ \theta θ是光线方向与视线方向的夹角,而 g g g表示散射的对称性。若 g g g是正值,则大多数光线会被粒子向后方散射;若 g g g是负值,则更多的光线会被向前方散射。通常,g取值[-0.75,0.99]。
③ 大气密度:对于瑞利散射和米氏散射,它们对太阳光的散射作用都和空气粒子的密度有关。许多大气模型都假设摄像机总是在地面上或者是在十分接近地面的位置,这样就可以认为空气具有一个恒定的粒子密度,这就在很大程度上简化了Nishita在1993年提出的散射积分方程,并在近地空间可以得到很好的渲染效果。然而在远离地表的高空,这种做法得到的渲染结果并不准确。
实际中的大气密度在地球引力的作用下,越靠近地表空气密度越高,越远离地表空气越稀薄。所以,我们假定空气粒子的密度是沿着海拔高度h呈指数递减的:
ρ = ρ 0 e − h H \rho=\rho_0e^{-\frac{h}{H}} ρ=ρ0e−Hh 其中 ρ 0 \rho_0 ρ0是在海平面的空气密度 (6)
h h h为当前采样点的海拔高度, H H H是缩放高度(在实现中可设为大气层高度)。理论上说大气层并没有确定的高度,但在实现中我们需要一个统一高度来渲染天空弯顶,这样空气密度随着高度的增加而呈指数递减。对于Rayleigh散射与Mie散射我们分别使用不同的缩放高度: H R = 7994 k m H_R=7994km HR=7994km, H M = 1200 k m H_M=1200km HM=1200km。这是因为影响Mie散射的大颗粒(尘埃、水滴等)更多的存在于近地表的对流层中,再往上Mie散射效果不明显,但Rayleigh散射的作用依然存在。
3、光线内散射
太阳光在大气中传输的时候会与空气中的微粒产生交互作用。有两种重要的交互方式:散射,它改变了光线的方向;吸收,它将光能吸收并转变为其它形态的能量(如热能)。而散射效果对场景中物体的影响又分为两个方面:一方面是一部分由物体反射的光被散射到视线之外,并不能到达摄像机,因而被衰减,称作外散射;另一方面是一部分太阳光被空气中的粒子散射正对向摄像机,这些正朝向视线的散射被称作内散射。
最后抵达视点被人眼所观察到的光线可分为两部分:衰减后的物体反射辐射度、被内散射的大气散射辐照度。
L v i e w e r = L o b j e c t ⋅ e − T ( O → C ) + L i n s c a t t e r L_{viewer}=L_{object}\cdot e^{-T(O\to C)}+L_{inscatter} Lviewer=Lobject⋅e−T(O→C)+Linscatter (7)
其中 L v i e w e r L_{viewer} Lviewer为最终抵达摄像机的总光强, L o b j e c t L_{object} Lobject为物体的反射光(当视线不与物体相交时则为 0 0 0), L i n s c a t t e r L_{inscatter} Linscatter为从O到C点路径上所有内散射光线的总和,这里暂时忽略太阳直射。
公式(7)中的 e − T ( O → C ) e^{-T(O\to C)} e−T(O→C)是光线从O点到C点的衰减系数,其中 T ( O → C ) T(O\to C) T(O→C)被称作光学深度(Optical Length),它是散射系数与密度乘积在整条路径上的积分。
① 光学深度:在上图中,大气层内有一点 P P P,它在视线 C O CO CO上。太阳光线照向地球,在穿过大气层的时候会受空气分子和空气溶胶的散射作用而发生衰减(外散射的影响),最终到达 P P P点处的光能总量为:
L p = L s u n e − T ( A → P ) L_p=L_{sun}e^{-T(A\to P)} Lp=Lsune−T(A→P) (8)
其中 L s u n L_{sun} Lsun是太阳光到达大气层前的初始辐射度。上图中 A A A点是光线到达 P P P点之前与大气层的交点,则 T ( A → P ) T(A\to P) T(A→P)被称作 A A A点到 P P P点的光学深度(Optical Depth),它本质上就是 A A A点到 P P P点这条路径上散射系数乘上空气密度的积分(包含Rayleigh散射与Mie散射):
T ( A → P ) = ∫ A P ( β R e e − h ( t ) H R + β M e e − h ( t ) H M ) d t T(A\to P)=\int_A^P(\beta_R^ee^{-\frac{h(t)}{H_R}}+\beta_M^ee^{-\frac{h(t)}{H_M}})dt T(A→P)=∫AP(βRee−HRh(t)+βMee−HMh(t))dt (9)
公式(9)中的参数前面都已提到过: β R e \beta_R^e βRe即Rayleigh散射系数, β M e \beta_M^e βMe是Mie散射系数,而形如 e − h H e^{-\frac{h}{H}} e−Hh的则分别是Rayleigh散射粒子密度分布函数、Mie散射粒子密度分布函数。在这里我们散射系数当作一个在海平面上的常数值,则式(9)可变为如下形式:
T ( A → P ) = β R e ∫ A P e − h ( t ) H R d t + β M e ∫ A P e − h ( t ) H M d t T(A\to P)=\beta_R^e\int_A^Pe^{-\frac{h(t)}{H_R}}dt+\beta_M^e\int_A^Pe^{-\frac{h(t)}{H_M}}dt T(A→P)=βRe∫APe−HR