在本章中,我们介绍一种简单的后处理方法,该方法能够产生因大气中阴影而造成的体积光散射效果。我们改进了现有的日光散射分析模型,使其包含体积遮挡效果,并展示了它在像素着色器中的实现方式。本书附带的DVD中包含了演示示例,该示例表明这项技术可应用于任意场景复杂度的任何动画图像。演示示例的屏幕截图如图13 - 1所示。
图13 - 1 实时在高度动画化场景中的体积光散射。
13.1 介绍
在现实世界中,我们很少会看到物体处于真空环境里(即物体与其观测者之间空无一物的情况)。在实时渲染中,由于辐射传输方程(延森和克里斯滕森,1998 年)在考虑复杂交互动画环境中的发射、吸收以及散射问题时,其性质棘手难处理,所以参与介质对光传输的影响往往遵循低复杂度的均匀性假设。在本章中,我们探讨大气中体积阴影对光散射的影响,并展示如何通过将 GPU 像素着色器后处理应用于一个或多个图像光源,来实时计算这种影响。
13.10 引用
Dobashi, Y., T. Yamamoto, and T. Nishita. 2002. "Interactive Rendering of Atmospheric Scattering Effects Using Graphics Hardware." Graphics Hardware.
Hoffman, N., and K. Mitchell. 2002. "Methods for Dynamic, Photorealistic Terrain Lighting." In Game Programming Gems 3, edited by D. Treglia, pp. 433–443. Charles River Media.
Hoffman, N., and A. Preetham. 2003. "Real-Time Light-Atmosphere Interactions for Outdoor Scenes." In Graphics Programming Methods, edited by Jeff Lander, pp. 337–352. Charles River Media.
James, R. 2003. "True Volumetric Shadows." In Graphics Programming Methods, edited by Jeff Lander, pp. 353–366. Charles River Media.
Jensen, H. W., and P. H. Christensen. 1998. "Efficient Simulation of Light Transport in Scenes with Participating Media Using Photon Maps." In Proceedings of SIGGRAPH 98, pp. 311–320.
Karras, T. 1997. Drain by Vista. Abduction'97. Available online at www.pouet.net/prod.php?wh….
Max, N. 1986. "Atmospheric Illumination and Shadows." In Computer Graphics (Proceedings of SIGGRAPH 86) 20(4), pp. 117–124.
Mech, R. 2001. "Hardware-Accelerated Real-Time Rendering of Gaseous Phenomena." Journal of Graphics Tools 6(3), pp. 1–16.
Mitchell, J. 2004. "Light Shafts: Rendering Shadows in Participating Media." Presentation at Game Developers Conference 2004.
Nishita, T., Y. Miyawaki, and E. Nakamae. 1987. "A Shading Model for Atmospheric Scattering Considering Luminous Intensity Distribution of Light Sources." In Computer Graphics (Proceedings of SIGGRAPH 87) 21(4), pp. 303–310.
13.2 云隙光
在合适的条件下,当一个空间包含足够密集的光散射介质混合物(比如气体分子和气溶胶)时,遮挡光线的物体将会投射出体积阴影,并且看上去会产生从光源辐射而出的光线。这些现象有着不同的叫法,如曙暮光条、太阳光柱、太阳耀光、星光闪烁、上帝之光或光轴。在太阳光下,此类光的体积实际上是平行的,但从透视角度看,它们似乎是从太阳向外发散的。
最初,在非实时渲染中,人们利用改进的阴影体算法(马克斯,1986 年)来处理渲染曙暮光条的问题,此后不久,又开发出了一种适用于多个光源的方法(西田等人,1987 年)。这一主题在实时渲染中又被重新探讨,当时采用的是基于切片的体渲染技术(多巴希等人,2002 年),而近期则利用硬件阴影图来应用该技术(米切尔,2004 年)。然而,基于切片的体渲染方法可能会出现采样伪影,需要较高的填充率,并且还要求额外的场景设置。虽然阴影图方法提高了效率,但它同样存在基于切片方法的那些缺点,而且还需要更多的显存资源以及渲染同步。另一种实时方法以拉多米尔・梅赫(2001 年)的研究成果为基础,使用多边形体(詹姆斯,2003 年),在该方法中,通过带有深度剥离的帧缓冲混合来累积重叠的体。一种类似的方法(詹姆斯,2004 年)利用累积的体厚度,免去了深度剥离的需求。在我们的方法中,我们应用了一种逐像素后处理操作,该操作无需预处理或其他场景设置,并且能够在任意复杂度的动画场景中呈现出细节丰富的光柱。
在先前的工作(霍夫曼和普里瑟姆,2003 年)中,实现了一种用于均匀介质中光散射的 GPU 着色器。我们通过一个后处理步骤对其进行了扩展,以考虑体积阴影因素。这种后处理的基本表现形式可以追溯到一种图像处理操作 —— 径向模糊,它出现在许多计算机图形(CG)演示作品中(卡拉斯,1997 年)。尽管那些演示作品是利用软件光栅化来应用后处理效果的,但我们使用硬件加速的着色器后处理,以便基于日光的分析模型进行更复杂精细的采样。
13.3 体积光散射
为计算每个像素处的光照情况,我们必须考虑从光源到该像素的散射情况,以及散射介质是否被遮挡。就太阳光而言,我们从已有的日光散射分析模型(霍夫曼和普里瑟姆,2003 年)入手。回顾如下内容:
方程1
其中, 是光线在介质中传播的距离,是光线与太阳之间的夹角。是来自太阳的源光照,是由光吸收和外向散射特性构成的消光常数,是由瑞利散射和米氏散射特性构成的角散射项。该等式的重要之处在于,第一项计算了从发射点到观测点所吸收的光量,第二项计算了因光散射进入观测光线路径而增加的光量。正如在霍夫曼和米切尔2002年的研究中那样,此处将诸如云、建筑物及其他物体这类遮挡物所产生的影响简单地建模为对源光照的一种衰减。
方程2
其中,是针对观测位置的、受太阳遮挡物体综合衰减后的不透明度。 这种考量带来了一个复杂问题,即需要确定图像中每个点处光源的遮挡情况。在屏幕空间中,我们没有完整的体积信息来确定遮挡情况。不过,我们可以通过在图像空间中对沿指向光源的光线进行采样并求和,来估算每个像素处的遮挡概率。命中发光区域的采样数量与击中遮挡物的采样数量之比,能为我们提供所需的遮挡百分比。在发光区域比遮挡物体更亮的情况下,这种估算方法效果最佳。在13.5节中,我们会介绍处理不存在这种对比度场景的方法。
方程3
13.3.1 对求和进行控制
此外,我们引入衰减系数来对求和进行参数化控制。
方程4
其中,“曝光”参数控制后处理的整体强度,“权重”参数控制每个样本的强度,而“衰减系数(取值范围在([0, 1])内)”会随着光线远离光源逐渐减弱每个样本的贡献。这个指数衰减因子实际上能让每条光柱在远离光源时平滑地减弱。
“曝光”和“权重”因子都只是比例因子。增大这两个因子中的任何一个,都会提高最终结果的整体亮度。在演示示例中,样本权重可进行精细调节,而曝光则通过粗粒度控制来调整。
由于样本完全源自源图像,所以无需额外操作就能处理半透明物体。对于每个投射光线的光源,可以通过在屏幕空间中连续进行加法处理来应用多个光源。尽管在上述解释中我们使用了分析性的日光模型,但实际上,任何图像源都可以被采用。
对于太阳的位置以及每个屏幕空间图像位置,我们通过沿着光线向量按固定间隔从源图像中连续采样来实现求和运算。在此,我们引入“密度”这个参数,以便在我们希望减少样本迭代的总次数,同时又能保持足够无混叠的采样密度的情况下,对样本之间的间隔进行控制。如果我们增大密度因子,样本之间的间隔就会减小,从而产生覆盖范围更短但更明亮的光柱。
在图13 - 2中,来自(位置)1的样本没有被遮挡,这使得在常规计算时能产生最大的散射光照。在(位置)2处,沿光线的一部分样本击中了建筑物,因此累积的散射光照就变少了。通过对图像中每个像素所投射光线进行求和,我们就能生成包含被遮挡光散射的体积效果。
图13 - 2 屏幕空间发射光线
我们可以通过对源图像进行下采样来降低带宽需求。通过滤波操作,这能够减少采样伪影,并且由于滤波核的作用,还会引入通过邻域采样产生的局部散射贡献。在演示示例中,一个基本的双线性滤波器就足够了。
13.4 后期处理的shader
这项技术的核心是后处理像素着色器,如代码清单13 - 1所示,它实现了公式4中的简单求和运算。
给定初始图像后,会沿着从像素位置投射到屏幕空间光源位置的光线生成采样坐标。[1]屏幕空间中的光源位置是通过标准的世界 - 视图 - 投影变换计算得出的,然后经过缩放和偏移处理,以获得取值范围在[-1, 1]内的坐标。公式4求和运算中的连续样本会同时根据权重常数以及指数衰减衰减系数进行缩放,目的是对效果进行参数化控制。样本“密度”之间的间隔可以进行调整,并且作为最终的控制因素,最终合成的颜色会通过一个恒定的衰减系数“曝光”进行缩放。
示例13.1 加法采样的后处理着色器实现
float4 main(float2 texCoord : TEXCOORD0) : COLOR0 {
// Calculate vector from pixel to light source in screen space.
half2 deltaTexCoord = (texCoord - ScreenLightPos.xy);
// Divide by number of samples and scale by control factor.
deltaTexCoord *= 1.0f / NUM_SAMPLES * Density;
// Store initial sample.
half3 color = tex2D(frameSampler, texCoord);
// Set up illumination decay factor. half illuminationDecay = 1.0f;
// Evaluate summation from Equation 3 NUM_SAMPLES iterations.
for (int i = 0; i < NUM_SAMPLES; i++) {
// Step sample location along ray.
texCoord -= deltaTexCoord;
// Retrieve sample at new location.
half3 sample = tex2D(frameSampler, texCoord);
// Apply sample attenuation scale/decay factors.
sample *= illuminationDecay * Weight;
// Accumulate combined color.
color += sample;
// Update exponential decay factor. illuminationDecay *= Decay;
}
// Output final color with a further scale control factor.
return float4(color * Exposure, 1);
}
13.5 屏幕空间遮挡方法
如前文所述,在屏幕空间中进行采样并非纯粹的遮挡采样。由于表面纹理变化,可能会出现不理想的条纹。幸运的是,我们可以采用以下措施来应对这些不良影响。
13.5.1 遮挡预处理方法
如果我们将遮挡物体以黑色且无纹理的形式渲染到源帧缓冲中,那么针对光线生成的图像处理就会在此图像上进行。然后,再使用常规着色方式渲染遮挡场景中的物体,并将后处理结果以加法混合的方式融入场景中。这种方法与渲染无着色深度预通道这一常用技术密切配合,该常用技术用于限制全着色像素的深度复杂度。图13 - 3展示了所涉及的步骤。
图13 - 3 遮挡预处理效果
13.5.2 模板方法
在早期的图形硬件上,不使用预通道,而是通过使用模板缓冲或阿尔法缓冲也能实现相同的结果。图像中的主要发光元素(比如天空)会正常渲染,同时设置一个模板位。然后,渲染遮挡场景中的物体时不设置模板位。当进行后处理应用时,只有那些设置了模板位的样本才会对加法混合有贡献。
13.5.3 遮挡对比度方法
同样地,随着面向光源时效果强度的增加,可通过降低纹理内容的对比度、运用雾效、空中透视或光线自适应等方式来解决这个问题。任何能够降低遮挡物体的光照频率和对比度的手段,都有助于减少条纹伪影。
13.6 注意事项
尽管能够取得令人瞩目的效果,但这种方法也并非毫无局限性。在处理相对较近的光源时,如图13 - 4所示,来自背景物体的光柱可能会出现在前景物体的前方。在完整的辐射传输解决方案中,前景物体本应正确地遮挡住背景光柱。这种情况没有预想中那么明显的一个原因在于,它可以被视作相机镜头效果的一种体现,即光散射发生在场景前方的某一层中。在存在高频纹理物体的情况下,这种伪影也能够得以减少。
图13-4 处理的局限性
当遮挡物体越过图像边界时,光柱会闪烁,这是因为它们超出了可见样本的范围。可以通过渲染屏幕周围的扩展区域来扩大可寻址样本的范围,从而减少这种伪影。
最后,当垂直朝向光源时,光在屏幕空间中的位置可能趋于无穷远,因而会导致样本之间间隔过大。可以通过将屏幕空间中的位置限定在一个合适的保护区带内来缓解这一问题。或者,也可以让该效果朝着垂直方向逐渐减弱,并且在使用遮挡方法时,这种效果还能进一步被削弱。
13.7 示例
本书随附DVD中的演示使用了着色器模型3.0来应用后处理,这是因为所需的纹理采样数量超出了着色器模型2.0的限制。不过,通过使用带有模板遮挡方法的多次加法帧缓冲混合,在早期的图形硬件上也能几乎同样高效地实现该效果,如图13 - 5所示。
图13.5 在固定功能硬件上通过多次加法帧缓冲通道实现的曙暮辉(云隙光)效果。
13.8 扩展
可以采用较低的分辨率进行采样,以降低纹理带宽需求。进一步的增强手段是通过随机采样改变采样模式,这样就能在降低采样密度的情况下减少规则图案伪影。 我们的方法通过单次执行着色器来完成后处理。在一种多通道方法中,可以执行像素着色器求和运算,即从光源发出的同心矩形带的结果可以累加到连续的外层带中,其中。虽然这种方法可能不太适合当前的硬件设计,但它代表了所需采样和计算的最小极限。 要在光柱强度和避免过度饱和之间达成平衡,就需要对衰减系数进行调整。一个能够根据光线自适应来实现图像色调平衡的解析公式,或许可以提供一种自动获取视觉效果一致图像的方法。例如,我们或许可以评估图像中的平均、最小和最大光照值的组合,然后应用一个校正颜色渐变,从而避免图像出现过度的光晕或暗沉现象。
13.9 总结
我们展示了一种简单的后处理方法,该方法能够呈现出因大气中阴影而产生的体积光散射效果。我们扩展了现有的日光散射分析模型,使其涵盖了体积遮挡的影响,并且描述了它在像素着色器中的实现方式。演示表明,这是一种实用的技术,可应用于任意场景复杂度的动态图像。