前言
关于经典老番,是指那些做某些效果必看的内容。本篇是非常著名的Precomputed Atmospheric Scattering https://hal.inria.fr/inria-00288758/en,发表于2008年,是基本上做预计算大气散射必看的文章。
为什么会写这篇?大气散射内容多而且杂,并且理解起来很麻烦,是我TA做了一年多认为最不好理解的内容之一,有工程难度Debug也很难找参考也得啃很久.... 在做到预计算大气散射的部分这篇基本也绕不开,但是当时只是浅看一下就跑去Github看了SlightMad的实现SlightlyMad ,这导致很多细节当时都没很好的吸收理解。这次借这篇文章,重新从头到尾理一下,不但是一个翻译,也是一个重新理解温故知新的过程。
本文会不仅仅包含翻译,还会夹杂简化的理解和我自己的理解。
当然我觉得为什么需要翻译是因为这篇论文的符号真的太多太专业,导致如果不做翻译我看了后面忘了前面,太难顶了【AMD的关于大气散射的两篇论文就相对来讲比较适合新人入门,比较好看懂,符号用的也不多】。
当然,最后要说的就是本文以翻译为主,自己理解为辅,遇到有些地方可能存在偏差和理解的出入,以论文原文为准。
翻译以及我的理解【部分翻译部分为了方便理解做了简化】
第一节 介绍 Section 1.Introduction
在许多应用中,大气效果对于增加户外场景的真实感非常重要。天空颜色代表着时间的流逝,而大气透视则为评估距离提供了重要依据。在许多游戏或应用程序(例如飞行模拟器或 Google 地球等地球浏览器)中,需要实时渲染这些效果,从地面到太空。对于以现实主义为目标的应用程序来说尤其如此,例如 Celestia 或 Nasa WorldWind。然而,这些应用程序目前使用非常基本的模型来渲染这些效果,这些模型不能提供逼真的图像。在本文中,我们提出了一种从地面到空间的任何视角实时渲染这些效果的方法。这种方法考虑了多重散射,这对于正确渲染暮光或地球在大气层中的阴影很重要。它基于适度的简化假设,使我们能够获得渲染方程的更好近似解(与以前的工作相比),其中大多数项都可以预先计算。我们的方法是第一个考虑所有视点、所有视图和太阳方向以及多重散射的实时方法。接下来的部分组织如下。第 2 节介绍了物理模型和渲染方程并回顾了相关工作。第 3 节介绍了我们的解析方法,以获得可预计算的公式。第 4 节和第 5 节介绍了我们的预计算和渲染算法。第 6 节给出了实现细节并展示了我们的结果。
[^]: 事实上在预计算大气散射之前,大气散射得纯raymarching 的去做,要达到非常完美的效果必然需要非常多的步进次数,这样也导致在机能有限的平台是基本上跑不动的,而预计算的提出,就可以完美的通过Lut的方式,内存换时间,把raymarching的内容放到了Lut中,显著的缩短了渲染的耗时
第二节 大气散射模型 Section 2.Atmospheric Models
渲染大气光照依赖于两个方面:局部介质属性的物理模型【也就是大气散射光学路径上每个微分点的属性】,以及基于观察者眼睛的GI的模拟。这包括与地面打交道【也就是所谓的大气透视】,可以将其建模为一个具有关于反射率 α(x,λ)、法线 n(x) 等等的高度场构成的兰伯特表面。大多数计算机图形学 (CG) 论文,从 [NSTN93] 开始,都依赖于包含空气分子和气溶胶颗粒的介质物理模型,总结于 第 2.1 节。然而,参与媒体的经典渲染方程在大气 CG 模型中很少被完全解释,尤其是对于交互式渲染。我们在第 2.2 节中重申了一般模型,并在第 2.3 节中介绍了它在以前的 CG 模型中的近似值
2.1 物理模型 Physical Model
CG中常用的物理模型是基于空气分子和气溶胶颗粒这两种成分的Clear Sky模型,在Rg = 6360 km和Rt = 6420 km之间的密度递减的薄球形层中。在每一点,偏离其入射方向θ的散射光的比例由散射系数 βs 和相位函数 P 【phase function】的乘积给出。βs 取决于粒子密度,相位函数P 描述了角度相关的散射概率。对于空气分子β s 和 P 由瑞利理论 给出:
其中 h = r -Rg
是海拔高度【r是大气最高点所在的球体的半径,Rg是地平线所在球体的半径】,λ是波长,n
是空气的折射率,N 是海平面的分子密度 ,HR= 8 km
是大气密度均匀时的厚度。在前人的论文中我们使用
与空气分子不同,气溶胶吸收一小部分入射光。它是用吸收系数β αM测量的,它给出了消光系数β eM = β αM +β sM 。请注意,折射率随高度的变化会导致光线的小幅弯曲(小于 2 度 )。为简单起见,我们忽略它.
2.2 渲染方程 Rendering equation
我们在这里回顾了应用于大气的参与介质中的渲染方程。我们注意到 L(x, v,
s) 是当太阳在 s 方向时从 v 方向到达 x 的光的辐射度,而 xo (x, v) 是射线
x +tv 的末端(见图 1)。请注意,xo 要么在地面上,要么在顶部大气边界 r =
Rt 上。 xo 和 x 之间的透射率 T、在 xo 处反射的光的辐射率 I 以及在 y 方向
-v 上散射的光的辐射率 J 定义为
这样的话,渲染方程如下:
2.3 之前的渲染方法 Previous rendering methods
最终的结果求解起来非常复杂。因此,在 CG 中进行了许多简化假设以找到近似值更容易计算。大多数实时方法忽略多重散射。在这种情况下,公式简化为 L = L0 + R[L0] + S[L0]。然而,即使是 S[L0] 也很难求解。一些作者以理想化为代价提出了分析解决方案:具有恒定大气密度的平坦地球,或没有米氏散射。平坦地球假说将它们限制在地面上的观察者身上。否则,S[L0] 通常通过数值积分计算,这可以使用低采样实时完成。然而,为了减少参数的数量,之前的论文他们只考虑了视角和太阳天顶角,而忽略了视角和太阳方向之间的夹角。因此,它们无法再现一些情况,例如,地球在大气层中的阴影。忽略上述多重散射对于日光是可以接受的,但对于暮光则不行。这是因为白天穿过大气层的阳光比日落或日出时少得多。因此,一些作者提出了解释多重散射的方法。 用解析模型拟合双散射 Monte-Carlo 模拟的结果,但他们的模型仅对地面上的观察者有效。使用体积辐射度算法来计算多重散射,但它们的方法远非实时(每张图像需要几分钟到几小时)。在本文中,我们提出了一种从地面到空间的所有视点实时渲染天空和空中视角的新方法,同时考虑到多重散射通过多重散射、以前忽略的视角-太阳角参数、对预先计算的表的更好参数化以及LightShaft的新方法进行了扩展。
第三节 我们的新方案 Section 3.Our Method
为了提高效率和真实性,我们的目标是尽可能多地预先计算 L,只使用最小的近似值。我们的解决方案基于零散射和单次散射的精确计算【零次就是sundisk,单次就是光路只改变一次就进入人眼】,并使用遮挡效应的近似值来计算多次散射。事实上,我们将详细的地面形状考虑到零散射和单次散射,以获得正确的地面颜色、阴影和光轴。但是我们用一个恒定反射率的完美球体来近似它来计算多重散射,以允许预先计算。
符号:
在介绍我们的方法之前,我们需要一些符号和辅助函数。我们注意到
零散射和单散射 我们在渲染期间精确计算 L0 和
R[L0]。为此,我们使用阴影算法来计算太阳遮挡【其实就是类似shadowmap的深度比较】,以及透射率
T 的预计算表,该表仅取决于 2 个参数(参见第 4 节)。 S[L0] 更复杂。它是
x 和 xo 之间的积分,但由于 L0 中的遮挡项,被积函数在阴影中的所有点 y
处为空(这就是产生LightShaft的原因)。我们在这里假设这些点在 xs 和 xo
之间(参见图 1——一般情况在第 5
节中讨论)。然后积分可以简化为光照渲染片段 [x, xs
]。此外,可以忽略遮挡,因为它已经通过 xs 计算,即 L0 可以替换为
多重散射如上所示,尽管有遮挡,仍可以准确计算 L0 和
L1。不幸的是,在其他项 L2 + L3+ . . Ln= R[L∗] + S[L∗]
要困难得多。希望在这种情况下,遮挡可以近似。实际上,与白天的单次散射相比,多次散射效应很小,而在没有直接被太阳照射时,地面贡献很小。因此,我们通过在
x 和 xs 之间集成多次散射的贡献来近似 S【L*
】中的遮挡效应,计算时没有遮挡。这会产生正偏差和负偏差(见图
1)。在数学上,这个近似给出了
我们还通过地面的切线使用水平半球的环境遮挡来近似 R[L*] 中的遮挡效果。
由此推导
第四节 预计算 Precomputations
我们为二维表 T(x, v) 中的所有 x, v 预先计算 T (x,
【简单来说就是每次微分位置的计算结果需要叠加,大气散射原理就是这样的】
角度精度 由于 S 是一个 4D
表,它的大小随着分辨率的增加而迅速增加。所以我们只能对 v
使用有限的角分辨率。这带来了一个精度问题,但仅限于强的前向 Mie
散射。为了解决它,我们将 S 中的单个 Mie
散射项与所有其他项分开,以便在运行时应用相位函数。为此,我们将
最后:
论文的后续内容都是一些实验结果和最后的展望,直接pass了,有兴趣的可以去细看原文。
虽然这篇论文真的写的蛮晦涩的,但是还是非常具有启发性,预处理的方法非常好,甚至可以去做一些缩减用到移动平台上。
举个例子,如果不需要渲染角色视角从地面到外太空的攀升变化,可以直接把起始点的高度输入去掉用定值代替【举个例子水平线的0】,去掉多级散射【别问,问就是不会】,等等操作去做简化计算,减少LUT的尺寸【主体思想还是用近似或者特殊情况去代替没必要的输入】