Unity 5 - BLACKSMITH深度分享之项目中的大气散射
Unity 5电影级大片Demo-BLACKSMITH在Unite上惊艳亮相,其带来的震撼让许多人至今难以忘怀。为了让更多Unity开发者了解这部大片是如何用Unity 5创作的,Unity的专家们深度分享了多篇技术干货,从各个维度详细解析BLACKSMITH的创作过程。
继上篇介绍了BLACKSMITH的概念设计与艺术创作后,本次将为大家介绍项目中的大气散射。此系列文章将同步在Unity官方微信平台和Unity中文官方社区更新,敬请持续关注。
早在Blacksmith的规划阶段,我们就希望设计出一个比内置雾气选项能提供更多控制和细节的大气散射方案,以呈现出如电影般波澜壮阔的空中透视效果。
散射方案的初步规划
在着手该项目的散射方案时,我们首先参考了Tomoyuki Nishita的几篇论文,并实现和测试了其中提到的一些模拟方案。在对各分镜进行初步实验和原型建模后,我们认为应采用一个能在各个分镜中都有出色艺术表现的方案。我们需要一个能从各方面逼真表现物理模型的解决方案,同时允许根据需求修改规则。此外,我们希望该方案不会对短片的运行效率造成太大负担,因此决定基于每个顶点而非各个像素进行运算。
我们的目标是对物理模型进行瑞利(Rayleigh)散射和米氏(Mie)散射的综合模拟,同时添加了用于表现各种低海拔散射的第三个元素,我们将其统称为高度散射。另一个关键决策是继续使用HDR天空纹理,而非通过程序生成天空和云彩。这样做的缺点是动态表现日夜变化会更困难,但好在Blacksmith项目没有这方面需求;其优势在于能充分保留我们对美术细节的控制能力。
瑞利散射
在现实世界中,瑞利散射使我们在白天能看到明朗的蓝天,在日出和日落时能目睹一片绯红。在模拟中,我们忽略了太阳本身,仅关注因日光输入输出带来的散射所产生的色彩和黯淡。太阳的视觉呈现可以添加到天空纹理中,或作为米氏散射的一部分,或利用太阳耀斑图片,也可以是它们的任意组合。
瑞利散射的核心部分,其密度归结为一个由瑞利相位函数调制的辉度指数。我们在输入和提取的数据中添加了一些额外控制。由于不模拟不同波长的光穿过大气层的情况,我们计算的密度为标量值。我们采用了HDR颜色斜坡,使入射散射光在水平到竖直向上范围内能呈现不同色调,并使用距离感知函数合成最终色相。
不同散射配置下的瑞利散射分量
不同的散射配置会导致瑞利散射呈现出不同的效果,具体表现可参考相关配置下的实际情况。
米氏散射
阳光在大气中的米氏散射造就了太阳的光晕、灰白色外观的云彩,以及受污染城市上空的雾霾。与瑞利散射均匀散射光线不同,米氏散射具有很强的方向性。在模拟中,我们利用米氏散射呈现雾霾和环绕太阳的光晕,因此频繁对其进行着色,以弥补瑞利散射中对太阳的忽略。
从技术角度,我们的瑞利散射和米氏散射所用函数相似,相位函数施加到输出的差异是它们最显著的区别。和许多其他实现一样,我们使用Henyey - Greenstein散射函数控制米氏散射的各向异性(即方向性)。
不同散射配置下的米氏散射分量
不同的散射配置会让米氏散射产生不同的视觉效果,具体可查看对应配置下的实际情况。
需要说明的是,一些研读相关论文的行家可能会对我们采用的名词有看法,但我们希望大家不过多在意这些细节。早期人们在描述“天空散射”时用“瑞利”,描述“太阳光晕”时用“米氏”,因此即便从物理模型到执行模型过程中这些名词被简化,我们仍沿用它们。
高度散射
高度散射呈现了大量低海拔散射效果的混合形态,包括辐射雾、地面霾和低洼云。在实现中,高度散射的计算相对简单:通过定义的海平面和高度衰减得出高度散射的密度,然后基于距离的指数密度进行缩放,最终得到我们期望的着色色调。
不同散射配置下的高度散射分量
不同的散射配置会使高度散射表现出不同的效果,可参考相应配置下的实际情况。
散射遮挡
由于散射主要由阳光向观察者的角度散射引起,当物体挡住太阳光芒时,应产生合理的遮挡。为处理这种情况,我们在缩减的、屏幕外的缓冲区内,对定向光的级联阴影贴图进行射线匹配,并累计射线方向上由遮挡引起的缩减量。
在将散射应用到输出像素时,我们利用边缘感知滤波器对遮挡贴图进行上采样,并用它合成像素的最终颜色。在合成阶段遇到了问题,因为我们的方案仅适用于单散射,不能简单屏蔽所有入射散射光,否则会得到黯淡、不自然的图像,也不想将方案扩展为更复杂和代价高昂的多重散射。最终,我们发明了“间接因数”,通过指定特定参数处理散射比例,避免过于直接。
不同散射配置下的正确遮挡
不同的散射配置会影响遮挡效果的呈现,具体可查看对应配置下的实际情况。
最终整合
最后,我们将瑞利散射、米氏散射和高度散射的分量叠加,得到一个不错的颜色组合。接着,我们要充分利用前面提到的遮挡缓冲区,使用不同的强度参数调整施加到直接散射、间接散射、云和天空的散射量的遮挡强度。
最后,将混合好的散射与所绘制的图像结合,通过累计的总消光使传输的图像变暗,再通过累积的入射散射亮化它,从而得到示例场景的最终合成图像。
最终的合成
合成后的图像呈现出大气散射的综合效果,是整个散射方案的最终成果。
演示
我们将大气散射部分抽离到了一个独立项目,你可以通过Asset Store下载它:点击下载。该项目除了包含构成这个方案的代码和着色器,还包含用于生成文中图片所展示效果的所有图像预设置,其中的readme文档说明了这些不同配置选项的含义。