模拟展现次表面散射的半透明材料的简易教程 VR资源

manew_JR 2017-09-27 17:32:05
材质展现的大多数(如果不是全部)光学现象可以通过模拟各个光线如何传播和相互作用而被复制。 这种方法在科学文献中被称为光线跟踪,对于任何实时应用来说,这通常相对计算量太高。 大多数现代引擎都依赖大量简化,即使不能再现真实感,也可以产生可信的逼近。 本教程介绍了一种快速,开销低且令人信服的解决方案,可用于模拟展现次表面散射的半透明材料。
 
 
 
本文有上下两篇
 
 
简介
 
Unity中的标准素材带有透明度模式,可以渲染透明材质。 在这种情况下,透明度是通过Alpha混合来实现的。 透明对象在现有几何体的顶部呈现,部分显示了背后的内容。 虽然这适用于许多材料,但透明度是一种更一般性质的特殊情况,称为半透明(有时也称为透明度)。 透明材料只影响它们通过的光线(左下方),半透明材料可以改变其路径(右下方)。
 
 
这个行为的结果应该是清楚的:半透明的物质会散开他们通过的光线,模糊他们背后的东西。 这样的行为在游戏中很少见,因为实现起来要复杂得多。 透明材料可以使用alpha混合来逼近实现,而不需要光线跟踪。 另一方面,半透明材料需要模拟光线的偏差。 这样的计算是非常昂贵的,并且在实时渲染中很值得。
 
这通常防止实现其他光学现象,例如子面散射。 当光照到半透明材料的表面时,部分在内部传播,在分子之间弹跳直到找到出路。 这通常会导致在特定点吸收的光被重新发射到其他地方。 子面散射导致在诸如皮肤,大理石和牛奶的材料中可以看到的漫射光。
 
 
实时半透明度
 
有两个主要障碍使半透明度如此昂贵。 第一个是它需要模拟材料内的光线的散射。 每束光线可以分割成多个,在材料中反射数百甚至数千次。 第二个障碍是,一点收到的光被重新发射到别的地方。 虽然这似乎是一个小问题,但实际上是一件大事。
 
为了理解为什么,我们首先要看看大多数着色器的工作原理。 在实时渲染领域,GPU希望着色器能够使用本地属性来计算材料的最终颜色。 对于每个顶点,着色器被设计为仅有效地访问该顶点的本地属性。 读取顶点的法线方向和反照率很容易; 检索其领域就不容易了。 大多数实时解决方案必须解决这些限制因素,并且找到一种方法来假定材料内的光的传播,而不依靠非本地信息。
 
本教程中描述的方法是基于ColinBarré-Brisebois和Marc Bouchard在GDC 2011中提出的一个解决方案,即“快速,低开销和令人信服的子面散射外观”的近似半透明度。 他们的解决方案被集成到Frostbite 2引擎中,用于DICE’s Battlefield 3游戏中.虽然没有物理准确性,Colin和Marc提出的方法以非常小的成本产生了非常可信的结果。
 
他们的解决方案背后的想法非常简单。 在不透明材料中,光的贡献直接来自光源。 相对于光的方向L倾斜超过90度的顶点不接收光(底部,左侧)。 根据演示中提出的模型,半透明材料具有与-L相关的额外的光贡献。 在几何学上,-L可以看作是一些光实际上通过材料并将其转化到另一侧(底部,右侧)。
 
 
每个灯现在占了两个,不同的反射贡献:前后照明。 由于我们希望我们的材料尽可能现实,我们将使用Unity的标准PBR照明模型作为前照明。 我们需要的是找到一种描述-L的贡献的方式,并以某种方式模拟材料内可能发生的扩散过程。
 
 
返回半透明度
 
如前所述,我们的像素的最终颜色依赖于两个组件的总和。 第一个是“传统”照明。 第二个是来自照亮我们模型背后的虚拟光源的轻微贡献。 这给人的印象是来自原始光源的光线实际上通过了材料。

要了解如何在数学上建模,让我们来看下面两种情况(下图)。 我们正在画红点; 由于它处于材料的“黑暗”一侧,所以应该由-L照亮。 从外部观察者的角度,我们分析两个极端情况。 我们可以看到V_B与-L完全一致,这意味着观众B应该充分看到后半透明度。 另一方面,观察者A应该看到与-L垂直的最小量的背光。
 
 
如果你不是着色器编码的新手,这种推理应该听起来很熟悉。 我们在Unity 5中的基于物理渲染和照明模型的教程中遇到过类似的事情,在这里我们展示了如何使用称为点积的数学运算符来获得这样的行为。
 
作为第一个近似值,我们可以说由于半透明度I_ {back}的背光照射量与V \ cdot -L成正比。 在传统的弥漫着色器中,这将是N \ cdot L.我们可以看到,我们在计算中没有包括表面法线,因为光线只是从材料中出来,而不是反射出来。
 
 
子面失真
 
然而,表面法线应在光线离开材料的角度方面具有一定的影响,即使较小。 这种技术的作者引入了一个称为子面失真\ delta的参数,迫使向量-L指向N.从理论上讲,这种子面失真控制了表面正常偏转出射背光的程度。 按照所提出的解决方案,后半透明组分的强度变为:

其中\ left \ langle X \ right \ rangle = \ frac {X} {\ left \ | X \ right \ |}是指向X的相同方向的单位向量。如果您熟悉Cg / HLSL,那么 是归一化函数。
当\ delta = 0时,我们返回到前一段中派生的V \ cdot - \ L。 当\ delta = 1时,我们正在计算视图方向与 - \ left \ langle L + N \ right \ rangle之间的点积。 如果您熟悉Blinn-Phong反射率,您应该知道\ left \ langle L + N \ right \ rangle是L和N之间的矢量。因此,我们将其称为direction H。
 
 

上图显示了迄今使用的所有方向。 H以紫色表示,您可以看到它位于L和N之间。几何学上,从0到1变化\ delta从而导致感知方向L的变化。光阴影区域显示方向的范围 背光将来自。 在下面的图片中,您可以看到\ delta = 0时,对象似乎从紫色光源照亮。 当\ delta向1移动时,光源的感知方向向紫色方向移动。
 
 

\ delta的目的是模拟某些半透明材料以不同强度扩散背光的趋势。 \ delta值较高会导致背光散射更多。
这个H与Blinn-Phong Reflectance中使用的H是一样的吗?

作者怎么没有使L + N正常化?
 
 
背光扩散
 
在教程的这一点上,我们已经有了一个方程,我们可以使用模拟半透明材料。 数量I_ {back}不能用于计算最终的光贡献。
 
有两种可以使用的主要方法。 第一个依靠纹理。 如果您想对材料中光线漫射的方式进行全面的艺术控制,您应该将I_ {back}夹在0和1之间,并用它来取样背光的最终强度。 不同的坡道纹理将模拟不同材料内的光线传输。 我们将在本教程的下一部分中看到,这可以用来显着改变这个着色器的结果。
 
然而,这种技术的作者使用的方法不依赖于纹理。 它使用Cg代码创建一个曲线:
 
 

两个新参数p(功率)和s(刻度)用于改变曲线的性质。
 
 
结论
 
这篇文章解释了渲染半透明材料的技术挑战。 引入了一个近似的解决方案,遵循近似半透明为快速,便宜和令人信服的地下散射观察提出的方法。 本教程的下一部分将重点介绍如何在Unity中的着色器中实际实现此效果。
 
如果您对更复杂的方法来模拟实时应用程序的子面散射,GPU Gems将提供您可以找到的最佳教程之一。
99VR视界二维码
热门推荐
Hot Recommended
在线客服