代码改变世界

基于物理的渲染详尽指南 卷1光与介质:基于物理的渲染和着色理论

2016-04-23 15:59  风恋残雪  阅读(4072)  评论(1编辑  收藏  举报

光与介质

基于物理的渲染和着色理论

此文对于程序员和美术制作人员都有很大的帮助作用,希望你看完后对基于物理的渲染有个整体的理解,此篇翻译的文章(The Comprehensive PBR Guide by Allegorithmic - vol. 1)基本上是从美术的角度来解释基于物理的渲染,有时间我会把程序部分的知识再细致讲一下,包括理论和实现,我自己目前也在学习阶段,主要在研究UE4的基于物理的渲染,希望在接下来的时间里出一个比较详细的文章来从程序员的角度详细阐述实现原理。

                                                                                                By 风恋残雪

                                                                                            博客:http://www.cnblogs.com/ghl_carmack/

光是一种复杂的现象,因为它同时具有波和粒子的属性。因此,创建了不同的模型来描述光的行为。作为制作贴图的美工,我们关心光-射线模型,因为它描述了光和介质是如何交互的。对于我们来说,理解光线如何跟介质表面交互很重要,因为我们的工作就是要制作描述那个表面的贴图。我们制作的贴图和材质用来在虚拟世界中跟光线交互,我们对光如何表面了解得越多,我们制作的贴图看起来就越好。

在这个指南里面,我们会讨论物理背后的理论,它是基于物理渲染的模型的理论基础。让我们从光线说起然后逐步扩展到基于物理渲染的关键因素。

光线(Light Rays)

光线模型表明光线在比如空气等的均匀透明介质中沿直线传播,它也表明射线在遇到不透明物体的表面或者穿过不同介质(比如空气到水中)时会有一个可以预测的行为。这样,显示光线从一个起点开始到最后转换成另一种形式的能量 比如热能的路径便成为可能。

到达表面的光线叫做入射光线,到达表面跟法线形成的夹角叫入射角,如图01所示。

光线在两种介质交界入是入射的。当光线到达表面时,两者之中或者两者全部会发生:

  1. 光线反射离开表面,并且以另外一个方向传播。它遵循反射定律,反射角等于入射角(反射光线)。
  2. 光线从一种介质进入另外 一种介质直线传播(折射光线)。

此时,我们可以说光线分为两个方向:反射和折射。在表面,光线被反射或者折射,也可以最终被介质吸收。然而,吸收并不发生在表面。

图01

吸收与散射(透明与半透明)

当光线在非均匀介质或半透明材质中传播时,光线可以被吸收或者散射:

  1. 通过吸收,光的强度由于它转换成另外一种形式的能量(通过是热能)而变小,它的颜色也会因为对不同波长光的吸收不同而发生改变,但是光线的方向不发生改变。
  2. 通过散射,光线的方向随机发生改变,偏差的大小 取决于材质。散射随机改变光的方向但是并不会改变强度。耳朵是一个很好的例子,因为耳朵很薄(吸收少),所以你可以看到散射的光从耳朵背后射出。如果没有散射而吸收又很少,那么光线可以直接穿过诸如玻璃的表面。比如,你在一个池子里面游泳,希望它是干净的,那么当你打开双眼时,你会在干净的水中看很远的距离。然而,让我们假设在同一个池子中,但是不很脏,水中的小颗粒会散射光,这样水的能见度就会低很多。

光线在这样的介质或者材质中传播得越远,它被吸收或散射的就越多。因此物体的厚度对光线吸收或散射的程度起一个绝对性的作用。那么一个厚度贴图可以用来描述Shader中物体的厚度,如图02所示

图02

漫反射和高光反射

高光反射是在表面被反射的光,就如我们在光线部分讨论的。光线经反射离开表面并且沿一个不同的方向传播。它遵循反射定律,在一个完全光滑的表面,反射角等于入射角。然而,大多数表面是不规则的并且反射的方向会根据表面的粗糙度来随机改变,知道这一点很重要。它改变了光的方向,但是光的强度并没有改变。

粗糙的表面会有一个较大且较暗的高光。光滑的表面会保持高光聚集,这样在特定的角度下它看上去会更亮或者说更强。然而两种情况下都是同等数量的光能被反射,如图3所示。

图03 越粗糙的表面有越大、越暗的高光

漫反射是经过折射的光。光线从一种介质传输到另外一种介质并且在物体内部散射了多次。然后它又被折射离开物体进入原来的介质里面,并且位置跟第一次进入时的位置差不多是同一个点,如果图04所示。

图04

漫反射材质是很能吸收的,这意味着如果折射的光线在材质里面传输过长的 话,它很有可能被完全吸收。这意味着光线不会从材质里面出来,它可能并没有传输多少的 距离。这就是为什么进入和离开表面的点之间的距离可以忽略不计。在传统着色系统中一直用于漫反射计算的Lambertian模型,不会计入表面粗糙度的影响,但是也有考虑粗糙度影响的Oren-Nayar模型。

同时拥有高散射率和低吸收率的材质有时候被称为参与介质(participating media)或者半透明材质。比如烟、牛奶、皮肤、翡翠、大理石。使用额外的次表面散射模型来渲染后三种物体是可能的,该模型会把光线进入和出射的点的距离计算进去。精确渲染如烟和雾此类变化多端的低散射率和吸收率的介质需要诸如蒙特卡罗模拟等更复杂的算法。

微表面理论

理论上,漫反射和高光反射都依赖于光线相交表面的不规则程度,粗糙度对于漫反射的影响比较小因为散射发生在材质内部。因此出射方向基本上跟表面的粗糙度和入射方向无关。最深用的漫反射模型(Lambertian)完全忽略它。

在这个文档里,我们把表面的不规则程度叫做粗糙度。实际上,它也有几个其它的名字,比如粗糙度、光滑程度、光泽度或者微表面,跟使用基于物理渲染工作流程有关,但是它们都是说的表面的同一个方面,它就是子纹素(sub-texel)几何细节。

表面的不规则程序表现在粗糙度或者光泽度贴图中,这取决于你使用的工作流程。一个基材物理的双向反射分布函数(BRDF)是基于微表面理论的,它假设表面是由所谓的不同方向的微小细节表面组成。每一个微小的平面都会根据它的法线方向在一个方向上反射光线,如图05所示。

图05

表面法线朝向光源方向和视线方向中间的微表面会反射可见光。然而,不是所有的表面法线和半角法线(half normal)相等的微表面都会反射光线,因为其中有些被遮挡(光源方向)或者掩蔽如上图05所示。

在微观层面上不规则的表面会造成光的漫反射。例如,模糊的反射是由于光线的散射造成的。反射的光线并不平等,因此我们收到的高光反射是模糊的,如图06所示。

图06在微观层面上不规则的表面会造成光的漫反射

颜色

表面的颜色(我们人眼看到的颜色)是由于光源发射出的波长和它被 物体吸收以及反射的漫反射和高光所决定的。剩下的被反射的波长的光就是我们看到的颜色。

例如,一个苹果的表面大部分反射红色的光线。只有波长为红色的光被散射回表面,其它的均被吸收了。如图07所示。

图07

它也有跟光源颜色相同的高光,因为像苹果这样的绝缘体的表面的材质高光反射几乎是独立于波长的。因此,这种材质的高光反射是基本是都是没有被修改过颜色的(跟光源的颜色相同)我们会在接下来的章节中讨论不同材质(金属和非金属)。

双向反射分布函数(BRDF)

双向反射分布函数简单来说就是一个描述表面反射属性的一个函数。在计算机图形学中,有很多的不同的BRDF的模型,其中一些并不是基于物理的。一个BRDF要满足基于物理的特性,它必须是能量守恒的且相互的。对于相互的,我是指亥姆霍兹倒易律,它表明入射和出射光线可以在不影响BRDF值的情况下相互交换。

Substance使用的基于物理渲染的着色器(shaders)是基于迪斯尼的理论反射模型的(虚幻引擎的也是基于这个理论修改简化而来),它是基于GGX微表面分布。GGX在高光分布上要比其它方案好,它有一个较短的高光峰值和在衰减的部分有一个较长的尾部,这样它看上去就比较真实。如图08所示。

图08

能量守恒

能量守恒在基于物理渲染的解决方案中扮演着关键的角色。它表明被表面重新发射的光的总能量(反射和散射回来的)是小于它接收到的能量的总数的。换句话说就是,经过反射离开表面的光不会比到达表面的光的强度更强。作为美术,我们没有必要担心如何控制能量 守恒。这是基于物理渲染的最好的一个方面,能量守恒通过 着色器(shader)来强制保证。它是基于物理模型的一部分,这样我们就可以花更多的时间在如何制作出好的效果上而不是关注于物理实现上。

菲涅尔效果(Fresnel Effect)

菲涅尔反射因子作为BRDF的一个系数在基于物理渲染中也是一个非常重要的角色。由法国物理学家Augustin-Jean Fresnel发现的菲涅尔效果声明你从一个表面看到的反射光线的数量取决于你接收它时的观察角度。

比如,假设有一池水,如果你垂直于水的表面直接向下看,你可以很清楚的看到底部(假设水比较清澈)。以这种方式来观察水的表面基本上为0度或者说是沿法线入射,法线是指表面的法线。现在,如果你以一个切线入射方向来观察水的表面,尽量平行于水面,那么你会看到水面上的高光反射变得更强,并且你可能完全看不到水底的样子。

基于物理渲染的菲涅尔效果并不像我们在传统着色模型中使用的那样。再次重申一次,它是基于物理渲染的着色器处理的另外一个物理特性。当在一个切线入射角观察表面时,所有光滑的表面在入射角为90度时会成为一个百分百的反射器。

对于粗糙表面来说,反射中高光部分会更多,但是不会达到百分百的高光反射。这个时候起决定作用的是微表面的法线和光线的夹角而不是宏观表面的法线和光线的夹角。因此光线被分散到不同的方向,反射会变得更柔和、更暗。在一个宏观层次上,你看到的效果可能 是微表面所有 菲涅尔效果的一个平均效果。

F0 (在0度角的时候菲涅尔反射值)

当光源垂直(0度角)到达表面时,其中一部分光作为高光反射回来。使用表面的折射率(IOR),你可以推导出反射回来的数量,这个值就被称为F0(Fresnel 0),如图09所示。被折射进入表面的光源的数量被称为1-F0。

图09对于粗糙表面来说,反射中高光部分会更多,但是不会达到百分百的高光反射

对于普通的绝缘体来说,F0的值一般在0.02到0.05之间,而对于导体来说F0的范围一般在0.5到1.0之间。因此 ,表面的反射能力是由下面的折射率公式决定的,如图10所示,它来自于Sebasien Lagarde's "Feeding a Physically-based Shading Model"这篇博文。

图10

F0的反射值是我们需要在制作贴图的过程中需要关注的。非金属(电介质/绝缘体)一般是一个灰度值,而金属(导体)会有一个RGB值。关于基于物理的渲染且从一个美术的角度来解释反射,我们可以说对于 普通的光滑绝缘体表面,F0会反射2%到5%的光线,而在切线角时会反射百分百的光线,如图09所示。

电介质的反射值 变化的并不剧烈,实际上,改变粗糙度时实际值的变化基本上看不出来。然而 ,值会有所不同。在图11里面,你可以看到一个展示金属和非金属材质F0范围的一个图表。

注意非金属的F0的范围并不会跟其它非金属有很大的不同。宝石是一个例外,它们有较高的值 。我们接下来会讨论F0,因为它跟导体和绝缘体有比较大的关系。

图11

导体和绝缘体(金属和非金属)

当创建基于物理渲染的材质的时候,我发现以金属和非金属来思考如何制作是很有用的。我会问自己这个表面是金属还是非金属。如果 是,我会遵循一系列准则,如果不是我会遵循另外一些准则。这个方法可能过于简单,因为有此材质并不会简单的归为金属或者非金属,比如准金属,但是在创建材质的整个过程中,区分金属和非金属是一个好的方法,除了准金属是个例外。为了给制作材质设置一些规则,我们首先必须要理解我们要创建什么。通过基于物理渲染,我们可以查看金属和非金属的属性来创建准则。

折射光线被吸收,金属的颜色来自于反射的光线,因此在我们的贴图中,金属没有漫反射颜色。

金属

金属(导体)是热和电的良好导体。简单来说,导体金属的电子场为0并且当一个由电和磁组成的光波到达表面时,其中的一部分被反射而另外一部分则被吸收。抛光金属的反射值一般在70-100%一个很高的范围内,如图12所示。

图12

一些金属吸收不同波长的光线。比如,金子吸收在可见光谱高频区域的蓝色光,因此它看上去会偏黄。然而 ,因此折射的光被吸收了,金属的颜色来自于反射的光线,因此在我们的贴图中,金属没有漫反射颜色。比如,在高光/光泽度工作流程中,纯金属在漫反射贴图中颜色为黑色,在高光贴图中反射值是一个上色的颜色值。对于金属,反射值 是一个RGB值并且是可以调节色彩的。由于我们使用的基于物理的模型,我们需要给我们的金属反射值使用真实世界测量的值。

另外一个关于金属制作贴图的一个需要注意的方面是金属可以腐蚀。这意味着风化在金属的反射状态中扮演着一个重要的角色。比如,如果金属生锈了,那么它就改变了金属的反射状态并且腐蚀的区域需要当做绝缘体材质来自处理,如图13所示。

图13

喷漆的金属会当做非金属而不是金属来对待。喷漆视为纯金属上的一个层。只有从掉落的漆裸露出来的纯金属才当做金属来对待。同样也适用于金属上的尘土或者任何挡住纯金属的介质。

如我上面所述,我经常问自己一个材质是金属还是不是。然而,更加精确地说,问题应该是获取金属的状态,比如它是不喷漆,生锈或者被尘土或者油脂遮挡。如果不是纯金属那么它就会被当做电介质来处理,也有可能因为风化造成纯金属和非金属的融合。

风化在决定金属的反射状态扮演一个重要的角色。

非金属

非金属(绝缘体/电介质)是电子的不良导体。折射光线被散射和吸收(通常会从表面重新发射)因此比起金属来它们反射很少一部分的光线,这样就得到一个漫反射颜色。我们前面说过,普通绝缘体的通过折射率计算的F0值在2-5%之间。这些值在线性空间中的范围为0.017-0.067之间(40-75 sRGB)如图14所示。宝石是个例外,大多数的非金属不会大于4%。

图14

就跟金属一样,它们也需要真实世界测量的值,但是不透明材质的折射率很难找到。然而,大多数 常见的电介质的F0值不会变化很大,因此我们可以遵循一些指南来找出反射的值,我们会在卷2中介绍。

常见电介质的F0反射值在2-5%之间,通过折射率计算而来(IOR)。

线性空间渲染

线性空间如果展开来讲就可以写一整篇文章。因此,我们不会深入细节。然而,我们需要知道光照计算必须在线性空间完成。

简单来说,线性空间渲染为光照计算提供了正确的数学方式。它为光照表现得跟真实世界一样创造了一种环境。在线性鹤立是内,gamma值 为1.0。然而,为了让我们人眼看起来正确,这些贴图需要使用sRGB编码。在Substance中,如果 图片标记了sRGB,那么它会被转换到线性空间为了以后的计算,最后会转换成sRGB编码来显示到屏幕上。然而,当你在纹理里面存储仅代表粗糙度或者金属度的数值时,这些图片需要在线性空间。

Substance自动处理线性和sRGB空间转换作为转入,也会对渲染视口中计算的结果进行gamma校正。作为美术人员,你不需要关心Substance中的线性空间的计算和转换。当通过Substance集成插件来使用Substance材质的时候,线性空间的转换会自动处理。

然而 ,理解过程很重要,因为当Substance贴图用来作为导出位图并且不是使用Substance材质时,你或许根据你使用的渲染器需要手动处理转换。你需要知道基础颜色/漫反射颜色是在sRGB空间,而其它的是在线性空间的。

关键点:

现在我们已经浏览了基本物理渲染背后的基础理论,我们可以得到基础物理渲染的一些关键点。

  1. 能量守恒。一个反射光线是不可能比它达到物体表面时更亮的。能量守恒是由着色器(shader)来保证的。
  2. 菲涅尔。双向反射分布函数由着色器来处理。F0反射值对于常见的电介质都差不多,范围在2-5%之间。金属的F0值范围比较大为70-100%之间。
  3. 高光强度通过双向反射分布函数来(BRDF),粗糙度或者光泽度贴图以及F0反射值控制。
  4. 光照计算是在线性空间进行的。所有gamma编码过的贴图,比如基础色或者漫反射通常是通过着色器来转换到线性空间的,但是你可能需要在你的游戏引擎或者渲染器里面通过选择相应的选项来确保正常转换。描述表面属性的贴图如粗糙度,光泽度,金属度或者高度图应该被设置为解释成线性空间的。

参考:

1. Physically-Based Shading at Disney Brent Burley, Walt Disney Animation Studios.
https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf
2. Microfacet Models for Refraction through Rough Surfaces
http://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf
3. Feeding a Physically-Based Shading Model by Sebastien Lagarde
http://seblagarde.wordpress.com/2011/08/17/feeding-a-physical-based-lighting-mode/
4. An Introduction to BRDF Models by Daniël Jimenez Kwast
http://hmi.ewi.utwente.nl/verslagen/capita-selecta/CS-Jimenez-Kwast-Daniel.pdf

整个文件也可以下载pdf: https://files.cnblogs.com/files/ghl_carmack/%E5%9F%BA%E4%BA%8E%E7%89%A9%E7%90%86%E7%9A%84%E6%B8%B2%E6%9F%93%E7%90%86%E8%AE%BA.pdf