一、常见的云渲染方案
- 基于纹理的云渲染
- 基于粒子系统的云渲染
- 基于几何体扰动的云渲染
- 基于体渲染的云渲染
以下表格对比了不同云渲染方案的优缺点:

二、何谓大气
所谓大气,是围绕行星或卫星等天体的气态物质外壳,在模拟地球大气的视觉特征时,我们需要考虑三种大气成分,它们分别是:
- 尺寸明显小于可见光波长的介质粒子,例如氧气和氮气等
- 大小接近或超过可见光波长的介质粒子,例如水滴
- 具有特殊视觉效果和单独密度分布的介质粒子,比如臭氧
因为地球引力和大气逃逸的存在,大气的介质粒子的分布密度通常随着海拔高度的提升而加速下降,可以将大气中的小分子和水滴的分布密度建模为随海拔变化的指数分布:
\[\rho(h)=e^{-h/H}\]$H$ 为计算密度分布所依赖的大气厚度尺度,一般而言,这个值较小的分子对应于 8km ,而对于水滴而言,这个值大致为 1~2 km 。
三、云的分类
云是大气中的水蒸气遇冷液化成的小水滴或凝华成的小冰晶,所混合组成的漂浮在空中的可见聚合物,因此,不同海拔的水滴密度分布变化塑造了形态各异的云。

1803 年, Luke Howard 根据云的形态对云类型进行了分类,并给出了对应的拉丁文命名,他在他关于云的变化的论文里列出了七种不同的云形态:
- 卷云(Cirrus):具备平行、弯曲或发散的纤维特征,可在任何方向或所有方向上延展
- 积云(Cumulus):凸形、锥形的云堆,从水平底部向上堆积
- 层云(Stratus):呈现为延伸的、连续的、水平的薄片,从下向上增加
- 卷积云(Cirrocumulus):小而清晰的圆形团块,紧密水平排列
- 卷层云(Cirrostratus):呈现为水平或略微倾斜的团块并向其圆周的一部分或全部方向衰减、向下弯曲或呈波浪状
- 积层云(Cumulustratus):卷层云与积云混合形态,或者看起来像是前者与后者的堆积混合
- 雨云(Nimbostratus):雨云是湿度含量高的一类混合形态云,底部是一个水平的层云状,卷云在其上方蔓延,而侧面则表现为积云
除了根据云的形态对云进行分类之外,还可以通过高度对这些云形态进行分类:
- 低云:卷云、积云、层云、层积云等
- 中云:高层云、高积云等
- 高云:卷云、卷积云、卷层云等
四、云的形态模拟
在这里,我们先考虑单朵的云该如何进行形态模拟,云具有不定形特征,通常的做法是采用噪声去模拟云的这种不定形特征。对于体渲染而言,虽然可以采用 2D 纹理或者 3D 纹理都可以实现体渲染效果,但一般地还是采用 3D 纹理。确定纹理维度后,自然地需要考虑应该采用何种噪声进行形态模拟, DECIMA 团队在 2015 年的一次分享中提到的 Perlin-Worley 噪声具备很好的云形态特征,这也是接下来要介绍的。
https://www.shadertoy.com/view/3dVXDc
(一)柏林噪声(perlin noise)
柏林噪声基于随机,并在此基础上利用缓动曲线进行平滑插值,使得最终得到噪声效果更加趋于自然,该噪声具备比较好的空间连续性,可以比较好地模拟自然界云的连续特性。

(二)沃利噪声(worley noise)
沃利噪声是细胞噪声的一类实现,具有明显的晶胞特征,该噪声的这一特征可以比较好地模拟自然界云的胞体状(当然为了符合云胞体的内部高密度向四周衰减的分布,应该使用所谓 1-worley noise)。

(三)分形布朗运动
一般而言,噪声具备良好的均匀分布,但自然界的云的内部粒子密度却不常遵从均匀分布,而更符合高斯分布,分型布朗运动通过不同权重混合计算不同频率的噪声,可以得到近似高斯分布的混合噪声。
https://iquilezles.org/articles/fbm/

(四)柏林-沃利噪声(perlin-woley noise)
DECIMA 团队在做关于他们的体积云制作经验分享时,提供的混合柏林噪声和沃利噪声的方案,可以很好地兼有两种不同噪声所具备的云特征,即较好的连续性和明显的晶胞效果。具体而言,他们提出,可以将柏林噪声以沃利噪声为下界,重映射到 0 ~ 1 的值域空间,从而得到所谓 perlin-worley 噪声。

(五)低频与高频噪声
在体积云制作中,通常以低频噪声构建云的基本形状,并通过高频噪声去侵蚀云的基本形状从而塑造单朵云的形状。具体而言,在云的形态模拟中,我们使用到 2 个 3D 纹理和 1 张 2D 纹理,下面将逐一介绍。
1. 低频噪声
用于构建云的基本形状的低频噪声是一个四通道的 3D 纹理,其 R 通道存储 perlin-worley 噪声,而 G、B、A 通道对应存储频率逐渐提升的 3 个 1-worley 噪声。

在运行时,通过将 G、B、A 三个通道的 1-worley 噪声进行 fbm 混合,并将该混合噪声用于去为 R 通道的 perlin-worley 噪声增加细节,从而得到相应的云密度属性。
\[SN_{sample}=Remap(sn_r,(sn_g*0.625+sn_b*0.25+sn_a*0.125)-1,1,0,1)\]之所以采用上述侵蚀方案而非使用全部四个通道进行 fbm 混合,是为了避免从云胞体中央区域侵蚀过多密度。
2. 高频噪声
另一个用于为云的基本形状增加细节的 3D 纹理具备 3 个通道,这三个通道对应存储频率逐渐提升的 3 个 1-worley 噪声,这三个通道的 1-worley 噪声与上述低频噪声中的 G、B、A 三个通道存储的 1-worley 噪声的不同处在于其频率相对更高。

但在运行时的使用上是类似的,即通过将该高频噪声的 R、G、B 三个通道进行 fbm 混合,并将混合结果用于侵蚀通过低频噪声得到的云的密度属性。
\[DN_{sample}=dn_r*0.625+dn_g*0.25+dn_b*0.125\](六)云的类别模拟
通过噪声和采样噪声,我们可以塑造出普通的云形状,但这样的云朵与现实中的云具有比较大的差异,关于这点,我们首先可以注意到上文提到的云的形态分类中很重要的一点是云因为水滴随着海拔高度变化具备的分布密度差异而具备了多种多样的云种类,相应地,可以通过密度关于海拔高度的分布函数进行建模。
一般的,通过所谓海拔-密度映射去对云的形状进行侵蚀或增益,该映射的提供有基于计算建模和基于纹理查表两种思路。
1. 数值模型
有两种常见的计算建模方法,一种是基于 Remap 函数,另一种是基于 Smoothstep 函数。 Remap 函数的功能是将一个值从一个定义域映射到另一个定义域。
remap(value, original_min, original_max, new_min, new_max)
{
return new_min + (((value - original_min) / (original_max - original_min)) * (new_max - new_min))
}
通过以下数值处理,可以塑造出一种海拔-密度映射:
float density = saturate(remap(height_fraction, bottom_start, bottom_end, 0.0, 1.0) * remap(heightFraction, upper_start, upper_end, 1.0, 0.0));
其中, height_fraction 是归一化的海拔高度(或理解为云层高度比例), bottom_start 、 bottom_end 、 upper_start 、 upper_end 是由下到上的云层底部羽化开始、云层底部羽化结束、云层顶部羽化开始、云层顶部羽化结束,通过给定不同的参数值,可以塑造得到不同的云类型的海拔高度-密度映射。

另一种基于 Smoothstep 的计算建模处理如下:
float density = smoothstep(bottom_start, bottom_end, height_fraction) - smoothstep(upper_start, upper_end, height_fraction);
其建模结果与 Remap 处理类似,参数含义相同,在此不再赘述。

正如云的形态分类中,积云、层云、层积云这一类名字所提示的那样,虽然有形态各异的不同云,但在模拟时,可以指定少数几种云的参数设置,并通过对少数几种云的参数进行插值,从而在指定的云形态间过渡产生更多的云类型。但如何在参数间插值仍然是一件需要注意的事情,是先得到映射再对输入参数得到的高度-密度映射进行插值,还是对参数先进行插值再拿插值参数取得到高度-密度映射是不同的,正确的做法是后者。
2. 纹理查表
除了通过数值方法对云随海拔变化而存在的密度变化进行建模之外,还可以通过预生产或运行时生成的纹理查表进行建模。在寒霜引擎的分享([Physically Based Sky, Atmosphere and Cloud Rendering in Frostbite])、R 星的分享([Advances in Real-Time Rendering in 3D Graphics and Games - SIGGRAPH 2019])以及 Unity HDRP 12.0 的体积云渲染中都采用了该种方式。
寒霜引擎的思路是将不同的云类型对应的高度-密度映射存储于 R 通道,将云的高度-侵蚀系数映射存储于 G 通道,从而实现更为细致的云类型的形态控制。

R 星的思路是通过将不同的云类型对应的高度-密度映射存储于纹理通道,并通过将不同的天气参数对应的云类型状态分存于不同通道,从而实现每一种天气参数能有独有的云类型分布。

Unity 的思路是将不同云类型对应的高度-密度映射存储于 R 通道,将云的含雨量存储于 G 通道,将云的 AO 信息存储于 B 通道,从而产生更多云细节。

五、天气分布
(一)通道设计
上文所介绍的云的形态模拟是针对单朵云的形态建模,对于一个区域而言,云的分布可以用天气分布进行描述,不同的体积云渲染系统有着不同的天气分布描述设计与方案。常见的一种方案是通过将天气分布记录于一张 2D 纹理,即所谓天气图,对于这样一张映射地面坐标的 2D 纹理而言,其四个通道分别存储哪些信息是我们需要关注的。
其中一种设计来自 DECIMA 的分享,他们将云的覆盖率存储于 R 通道,将云的湿度存储于 G 通道,将云的种类存储于 B 通道。

(二)纹理生成
1. 程序化生成
在确定完天气图的通道信息含义后的遇到的一个问题是,该如何生成这样一张天气图?相对程序化的思路是,继续使用噪声去生成天气图, DECIMA 的分享方案是使用柏林噪声生成云的覆盖率信息,这大抵是因为柏林噪声具有良好的连续性而云的分布覆盖也是相对连续的;而使用柏林-沃利噪声生成云的湿度信息,这是因为云的湿度与云的厚度形状有一定相关性,而柏林-沃利噪声能较好的模拟云的厚度分布形状。
2. 自定义
除了可以通过程序化生成之外,还有一种天气分布纹理生成思路,即依托于自定义绘制,这种方式的优势在于自定义程度高,但需要绘制者对于纹理各通道含义和分布合理性有所考量(当然在不加额外处理时,程序化生成在这块也是欠缺的)。自定义的其中一种实现方案是先将不同的云类型分布绘制到独立纹理,并绘制一张独立的湿度图,而后通过将这些纹理通过一定规则进行融合从而确定最终的天气分布纹理(这也是 Unity 2021.2 HDRP 中体积云渲染系统的设计方案)。
六、介质粒子与光照
https://www.pbr-book.org/3ed-2018/Volume_Scattering/Volume_Scattering_Processes
如果只是大气中具备这样那样的介质粒子,还不能构建出所谓的视觉效果,只有当光穿过大气介质,被人眼所接收时,方才完成了一次视觉传播过程。在介绍云的光照之前,有必要先了解一般的介质粒子的光照效应。

一般的,介质粒子存在四种不同的辐射变化,如上图所示,包括吸收(absorption)、外散射(out-scattering)、内散射(in-scattering)、自发光(emmission),有时候也会将内散射和外散射统称为散射。
(一)吸收(absorption)
介质的辐射度因为穿过其的光被其吸收而能量衰减,对于吸收而言,可以使用吸收率 $\sigma_a$ 表示穿过介质粒子的光子被吸收的比例:
\[e^{-\sigma a(x)dt}L(x,\overrightarrow{\omega})\](二)散射(scattering)
介质的辐射度还可能因为内散射而得到能量加强,或者因为外散射而受到能量衰减。
1. 外散射(out-scattering)
外散射是指光子通过介质粒子时被其反弹而散开的效应,相应地,光子在不同的方向上具备不同的反弹概率,这种不同方向上的光子反弹概率被称为相位函数 P :
\[L_i(x,\overrightarrow{\omega})=\int_{\Omega4\pi}P(x,\overrightarrow{\omega})d\omega\]https://www.pbr-book.org/3ed-2018/Volume_Scattering/Phase_Functions
(1)瑞利散射(Rayleigh scattering)
对于如氧气、氮气等这些粒子尺寸远小于可见光波长的大气介质粒子而言,其相位函数可以用瑞利散射函数表示,该相位函数呈现为较为均匀地四散分布,其一般可用于模拟大气散射:
\[R(\theta)=\frac{3}{16\pi}(1+\cos^2\theta)\](2)米氏散射(Mie scattering)
对于如水滴等这些粒子尺寸与可见光波长相近的大气介质粒子而言,其相位函数可以用米氏散射函数表示,该相位函数呈现出非常强的方向性,即大部分光将沿着光路前进方向反弹散射,而在其他方向上的反弹概率较低。云在日光下边缘呈现出的银边效果即是该效应的一个表现,另一个典型表现是所谓的丁达尔效应。

上图以方向箭头展现了瑞利散射和米氏散射的光子的反弹方向性上的不同。
2. 内散射(in-scattering)
内散射是指介质粒子接收来自其他介质粒子所反弹的光子而得到能量加强的效应,而因为上文所说的光子从介质粒子上反弹在不同方向上概率分布不均,所以对于内散射而言,不同方向的射入光子的贡献概率也是不均的,同样地使用相位函数进行描述。
(三)自发光(emission)
介质粒子的自发光是指其他形式的能量转化为光从而增强介质粒子的辐射度。例如,闪电即是比较典型的大气自发光现象。

上图集中展示了介质粒子的四种辐射变化及其对应的一般计算表达。
七、云的光照
云作为大气中水滴、冰晶的聚合物,太阳光穿过它们到达人眼的过程中,一般介质粒子(尤其考虑水滴这类与可见光波长相近尺度的介质粒子)的辐射度变化导致了我们所熟知的云光照现象。
- 因为吸收的存在,密度越大的云或则越厚的云,会显得越暗
- 因为外散射(尤其考虑米氏散射)的存在,遮挡在日光前的云常常伴有银边
- 因为内散射的存在,光子在云内部多次反弹,而在较薄处散射出,使得云呈现花椰菜般的高亮内褶
八、云的光照模拟

阳光通过云到达人眼的光路可以抽象为上图,对于云的光照模拟基于如上各辐射量得到(下面式子忽略掉了一般不考虑的自发光情况):
\[(\overrightarrow{w}\cdot\nabla)L(x\to\overrightarrow{w})=\underbrace{-\underbrace{\sigma_a(x)L(x\to\overrightarrow{w})}_{\text{absorption}}-\underbrace{\sigma_s(x)L(x\to\overrightarrow{w})}_{\text{out-scattering}}}_{\text{extinction}}+\underbrace{\sigma_s(x)L_i(x\to\overrightarrow{w})}_{\text{in-scattering}}\]除了上文介绍介质粒子与光照时提到的将外散射和内散射统称为散射这一种划分之外,还存在基于对辐射度增减的划分方式,在该划分方式下,吸收和外散射又被统合为消光项,这也是接下来将介绍的。
(一)消光(extinction)
消光是指光穿过介质过程中发生的辐射度下降,主要包含吸收和外散射这两个辐射变化部分。对消光的考量是对应于云的整体明暗,云中某一粒子的明暗是因为光照入云中存在部分光被该粒子所吸收、部分光被该粒子所外散。
\[\sigma_e = \sigma_a + \sigma_s\](二)透射率(transmittance)
一个比较容易和消光混淆的概念是透射率,透射率是指光穿过介质前后的辐射度变化,一般而言,光在穿过介质的过程中存在能量损耗,从而得到一个随着穿过介质距离增长而下降的透射率。
比尔-朗伯特定律(BeerLambert-Law)
http://life.nthu.edu.tw/~labcjw/BioPhyChem/Spectroscopy/beerslaw.htm
比尔-郎伯特定律是一种常用的透射率近似表达,该定律指出,可以通过光穿过介质的厚度来确定达到某个点的光量,根据这个定律,在体积云渲染中完全可以根据透射率和光线步进长度确定特定点的辐射能量,这也是云的光照模拟的关键。
\[e^{-density * absoption}\](三)Henyey-Greenstein 相位函数
https://web.archive.org/web/20141102063940/http://omlc.org/education/ece532/class3/hg.html
由于组成云的水滴的粒子尺寸接近或大于可见光波长,在云的光照模拟中主要考虑米氏散射这一各向异性散射的近似表达。一个比较常用的米氏散射近似函数是 Henyey-Greenstein 相位函数,该函数最早被用于天文尺度的光计算,而后被广泛用于模拟云的各向异性散射。
\[HG(\theta, g)=\frac{1-g^2}{4\pi(1+g^2-2g\cos\theta)^\frac 32}\]Henyey-Greenstein 相位函数中的 g 参数是各向异性参数,其物理意义是光入射和出射向量夹角的平均余弦值,当 g 参数为 0 时散射呈现为各项同性散射,当 g 参数大于 0 时散射呈现为前向散射,当 g 参数小于 0 时呈现为后向散射。
\[g= \begin{cases} <0 &\text{back scattering(most of the light is scattered back to the light source)} \\ =0 &\text{isotropic scattering(no scattering)} \\ >0 &\text{forward scattering(most of the light is scattered in the incident direction)} \end{cases}\]与真实的物理测量不同,在云的光照模拟中,通常选择把 g 参数作为属性提供给使用者。另外,对于相位函数的处理存在两方面考虑,其一是关于进行单次散射还是多次散射的选择问题,其二是如何兼顾前向散射和后向散射的问题。 对于第一个问题而言,一般地多次散射效果是优于单次散射的效果,但性能消耗也随着散射次数迭代次数增加而增加,出于性能考虑,采用单次散射不是不能接受;对于第二个问题而言,常见的前、后向散射兼顾处理包括 Lerp 操作和 Max 操作,这两种处理并无绝对的优劣之分,主要从实际效果感受进行选择。
Schlick 近似
事实上,虽然 Henyey-Greenstein 已经是一个非严格物理的米氏散射近似函数,但还有一个被称为 Schlick 近似相位函数的被用于近拟 Henyey-Greenstein 相位函数,从而进一步在实时渲染时减少计算量。该函数使用所谓 k 值的参数替代 Henyey-Greenstein 中的 g 参数,其函数表达如下:
\(k\approx1.55g-0.55g^3\) \(S(\theta, k)=\frac{1-k^2}{4\pi(1+k\cos\theta)^2}\)
(四)向光步进模式
在现实中,一般而言,云的光路传播始于太阳,然后在云内部发生吸收、散射,最后到达人眼,但在体积云渲染中,因为采用的光线步进技术是从屏幕向内投射射线,所以在云的光照模拟中光路是反向的,也因此对于云中的某点而言,去计算它的辐射度,需要做的是向光进行步进计算。
那么如何向光步进呢?比较直接的一种想法是直接向光的方向进行几次步进采样,去累计向光方向的一条射线截取线段的能量。

但如果考虑内散射的存在,这种直接的做法就忽略了来自其他方向上的介质粒子散射来的能量,因而又存在另一种更进一步的向光步进方案,即以当前计算的介质粒子为球心,构建一个球形能量采集范围,即球形步进。

而如果考虑到主要的能量来源于原始光源(如太阳)这一假设,则还存在另一种向光步进模式,即基于向光的方向为轴构建一个圆锥形能量采集范围,即锥形步进。

九、光线步进
(一)步进模式
光线步进可以简单理解为从相机位置向屏幕的每个像素投射射线,射线按照一定的步长行进,并检测、计算、处理当前光线位置点的表面属性,从而在虚拟空间构建视觉效果。
对于体积云渲染而言,则可具体概述为如下过程:
- 从相机位置出发,向屏幕的每个像素投射射线
- 射线以一定步长行进,在每个行进的阶段位点,对当前位置的云密度和辐射度进行检测
- 累计整个行进阶段的云密度和辐射度属性,即进行整条光路的离散化积分
形象地说,就像是一个检测仪器,从人眼的位置开始出发,向可见的物体方向走,走的路是笔直超前,这个检测仪器每过一段距离,就对当前位置进行检测,看,这里有没有云(比如说悬浮水滴密度是否大于0),看,这里光照能量是多少,就这一样一路走,一路记,直到到了该结束的时候,就该统计一下这一路下来云的累计密度、累计的光强,当然,这不是全部,在得到这些数据后仍然需要再进行数据处理(应用透射率计算、相位计算等),总而言之,这基本就是体积云渲染的光线步进的思路。

而对于步进而言,从哪里开始步进是一个需要考虑的点,简单的,当然可以直接从眼睛处开始步进,但面对类似云这种离开人眼距离十分遥远的东西而言,这是不合适的,因为如果这么做,前面的非常长一段距离都会是在做无用功,比如说,假如可以知道最近的云也离开人眼 1000 米,那从人眼位置出发,前面 1000 米便白白浪费了步进的检测。一个更为恰当的步进模式,是从尽量接近云的位置开始步进,一般的,正如现实中云位于大气层的一定高度到另一个高度的球壳状夹层中一样,可以在模拟中,使用所谓包围体的结构确定云的基本区域,这时候,便可以将问题转化为求解人眼出发的射线与包围体的关系,相交或不相交,如果相交又是从哪个位置开始相交,又从哪个位置结束,这些会在下一节介绍,在此先不赘述。
另外一个需要注意的点是关于光线步进的步长问题,选取多长的距离作为光线步进的单步长度,常见两种做法,其一是固定步长,其二是自适应步长。固定步长比较好理解,即每一次步进的距离是一致的;自适应步长则是根据射线在包围体中的行进总距离,去除以预期行进次数,得到单次行进距离。
事实上,对于步长的处理还有很多种,这些处理有时候是为了性能出发,如在未检测到有效信息时,光线进行快速步进(如以一般步长的二倍乃至更多进行行进);有时候是为了效果出发,比如对相对水平的光线采用更长步长,这是因为水平视距更远,更长的步长用以弥补检测不足的问题。
(二)两类包围体
虽然说现实中的体积云从大尺度来说,是存在于大气层这一球壳结构,但对于小尺度而言,则可以视为一个四方区域。相应地,在体积云模拟中,光线步进常见有两种不同的包围体设计;其一是仿现实地球的大气层包围体设计,简单来说就是由两个同心不同半径的球体所确定的带厚度球壳;

其二则是适合于较小区域更非现实的 AABB 类包围体;这两类包围体虽然不同,但在光线步进中我们所关注的点是一致的,即求得视觉射线与包围体的射入交点和射出交点。

iq 大佬整理了常见的射线与包围体交点检测的计算函数:
https://iquilezles.org/articles/intersectors/
(三)优化步进的分层现象
正如上面介绍光线步进原理时所说的那样,光线步进有如用检测器每隔一段距离进行一次信息检测,这种离散化地处理很好地解决了如何用计算机模拟现实连续的问题,但离散化总归不是连续,每一次的步进位点信息有了,但步进间隔却是存在的,相应地,就容易出现分层现象,即每一次步进间隔的信息确实导致的断裂感。
应对分层现象的一般做法是应用抖动,抖动是一种有意应用的噪声形式,用于随机化量化误差,从而防止图像中出现诸如色带之类的非预期效果。
1. 蓝噪声
蓝噪声是一类具有最小低频分量且没有集中能量尖峰的噪声,对于抖动而言是很好的噪声。
2. 随机序列
TODO
十、系统
许多游戏引擎或游戏团队根据他们的游戏设计、提供了体积云渲染系统。这篇文章主要参考的即是 DECIMA 团队在 SIGGRAPH 2017 分享的 NUBIS 系统,他们的体积云渲染系统分为天气图系统(Authoring System)、云密度建模(Cloud Density Model)、云光照系统(Cloud Lighting Model)、光线步进模块(Ray March)、后处理(Post Process),这种划分相对合理,各个模块各司其职。
Unity 引擎在 2021.2 版本的技术更迭中也在 HDRP 管线中推出了他们的体积云系统,该系统的功能划分也与 NUBIS 类似,包含天气图生成(基于不同云类型分布图进行混合)、云类型调整(基于曲线进行调整)等功能。
https://blog.unity.com/cn/technology/experience-true-volumetric-clouds-with-hdrp-unity-20212
十一、参考
(一)参考文档
- [Jarosz, 2009] W. Jarosz. “Rendering Participating Media”.
- [Schneider, 2015] A. Schneider. “The Real-Time Volumetric Cloudscapes Of Horizon: Zero Dawn”.
- [Bowles, 2015] Huw Bowles. “Sampling Methods for Real-time Volume Rendering”.
- [Hillaire, 2016] Sebastien Hillaire., “Physically Based Sky, Atmosphere and Cloud Rendering in Frostbite”.
- [Schneider, 2017] A. Schneider. “Authoring Real-Time Volumetric Cloudscapes with the Decima Engine”.
- [Bauer, 2019] F. Bauer. “Creating the Atmospheric World of Red Dead Redemption 2”.
(二)参考项目
- https://github.com/Straw1997/UnityURPCloud
- https://github.com/SebLague/Clouds
- https://github.com/ShaderFallback/UnityVolumeCloud
- https://github.com/yangrc1234/VolumeCloud
- https://github.com/kode80/kode80CloudsUnity3D
- https://github.com/jaagupku/volumetric-clouds
- https://github.com/sebh/TileableVolumeNoise
- https://github.com/Fewes/CloudNoiseGen
- https://github.com/mtwoodard/TextureGenerator