tingqiaoqiao

1.1.1   PBS的理论和数学基础

之前所学的章节中为Lambert模型、Phong模型、Blinn-Phong模型,它们都是经验模型,如果需要渲染更高质量的画面,这些经验模型就显得不再满足开发者的需求。

而今年来,基于物理的渲染技术(PBS, Physically Based Shading),被逐渐运用到实时渲染中。PBS是为了对光合材质之间的行为更加真实的建模。在Unity5中,standard shader可在不同材质之间通用的着色器,该着色器就是使用基于物理的光照模型。而PBS不意味着渲染出来的画面一定是像照片一样真实的,例如Pixar和Disney长期使用PBS渲染电影画面,但得到的风格非常有特色的艺术风格。而想要PBS实现出色的渲染效果,并不是一个纹理+shader的简单问题。

    

什么是光:

    光由太阳或其他光源中倍发射出来,然后与场景中的对象相交,一些光线被吸收(absorption),而另一些则被散射(scattering),最后光线被一个感应器(如我们的眼睛)吸收成像。

    材质和光线相交会发生两种物理现象:散射和吸收(还有自发光)。光线会吸收是因为由于光被转换成了其他能力,但吸收并不会改变光的传播方向。相反的,散射并不会改变光的能量,但会改变它的传播方向。在光的传播过程中,影响光的一个重要的特性是材质的折射率(refractive index)。而在均匀的介质中,光是沿直线传播的,但如果光在传播时截止的折射率发生了变化,光的传播方向就会发生变化。而如果折射率是突变的,就会产生光的散射现象。

    而为了在渲染中对光照进行建模,往往开发者只考虑一种特殊情况,只考虑两个介质的边界是无限大并且是光学平滑的(optically flat)的。而尽管真实物体的表面并不是无限延伸的,但也不是绝对光滑的。而和光的波长相比,它们的大小可以被近似认为是无限大以及光学平滑的。在该前提下,光在不同介质的边界会被分割成两个方向:反射方向和折射方向。而有多少百分比的光会被反射(另一部分是折射)则是由菲涅尔等式(Fresnel equations)来描述的。

    而对于有些物体看起来粗糙,有些物体看起来光滑,这是因为虽然一个光滑物体的表面仍然由许多凹凸不平的微表面构建而成,但是这些微表面的法线方向变化角度小,而因为表面反射的光线方向变化比较小,从而物体的高光反射更加清晰。而粗糙物体则相反,由此得到的高光反射效果更加模糊。

    而对于这些光,这些光被折射到物体的内部,一部分被介质吸收,一部分又被散射到外部。而金属材质具有很高的吸收系数,因此所有被折射的光往往会被立刻吸收,被金属内部的自由电子转换成其他形式的能量。而非金属材质则会同时表现出吸收和散射两种现象,那些被散射出来的光又被称为次表面散射光(subsurface-scattered light)。

而从渲染的层级大小上考虑光和表面一点的交互行为。那么由微表面反射的光可以被认为是该点上一些方向变化不大的反射光。而这些离入射点的距离值和像素大小之间的关系会产生两种建模效果。如果这些像素大于这些散射距离的话,则意味着这些次表面散射产生的距离可以被忽略,渲染就可以在局部进行。而如果像素要小于这些散射距离,则不可以选择忽略它们,要实现更真实的次表面散射效果,则需要使用特殊的渲染模型,即所谓的次表面散射渲染技术。

双向反射分布函数(Bidirection Reflectance Distribution Function, BRDF):

    可以利用辐射率(radiance)来量化光。辐射率时单位面积、单位方向上光源的辐射通量,通常用L来表示,被认为是单一光线的亮度和颜色评估。在渲染中,开发者通常会给予表面的入射光线的入射辐射度Li来计算出射辐射率Lo,这个过程也往往被称为是着色(shading)过程。

    而如果要得到L0,则需要知道物体表面一点是如何和光进行交互的,在该过程可以使用BRDF(双向反射分布函数(Bidirection Reflectance Distribution Function))。BRDF可以用f(l,v)来表示,其中l为入射方向和v为观察方向(双向的含义)。这种情况下,绕着表面法线旋转入射方向或观察方向并不会影响BRDF的结果,这种BRDF被称为各项同性(isotropic)的BRDF。与之相对应的是各向异性的(anisotropic)的BRDF。

    对于BDRF有三种理解方式:

       [1]给定入射角度后,BRDF可以给出所有出射方向上的反射和散射光线的相对分布情况;

       [2]当给定观察角度后(即出射方向),BRDF可以给出从所有入射方向到该出射方向的光线分布;

       [3]当一束光线沿着入射方向l到达表面某点时,f(l,v)表示了又多少部分的能力被反射到了观察方向上。

 

反射等式:

 

    给定观察视角v,该方向上的出射辐射率L0(v)等于所有入射方向的辐射率积分乘以它的BRDF值f(l,v),在乘以一个余弦值(n.l)。即可以理解为,如果要想计算表面上某点的出射辐射率,开发者已知到该点的观察方向,该点的出射辐射率是由许多不同方向的入射辐射率叠加后的结果。其中,BDRF表示了不同方向的入射光在该观察方向上的权重分布。开发者把这些不同方向的光辐射率(Li(l))部分乘以观察方向上所占的权重(f(l,v)部分),再乘以它们在该表面的投影结果((n.l)部分),最后再把这些值加起来(即做积分)就是最后的出射辐射率。

    而通常在计算的过程中,开发者所选用的都是精确光源(punctual light sources),l(c)来表示它的方向,C(light)来表示它的颜色。使用精确光源可以大大简化反射公式。

某个观察方向v上的出射辐射率:

 

对于着色过程是否基于物理的,可以由BRDF是否满足两个特性来判断:它是否满足交换律(reciprocity)和能量守恒(energy conservation)。

交换律:

 

而能量守恒则是要求表面反射的能量不能超过入射的光能:

 

基于这些理论,BRDF可以描述两种不同的物理现象:表面反射和次表面散射。针对每种现象,BRDF通常会包含一个单独的部分来描述——而用于描述表面反射的部分被称为高光反射项,而用于描述次表面散射的漫反射项(diffuse term)。

 

Unity中的PBS实现:

    Unity内置的UnityStandardBRDF.cginc提供了一个万能的shader,美工人员只需要调整少量参数就可以渲染大多数常见的材质。

    Unity5提供了两种PBS模型,一种是基于GGX模型,另一种是基于归一化的Blinn-Phong模型。这两种使用了不同的公式来计算高光反射项中的法线分布函数和阴影。

1.1.2   Unity5的Standard Shader

Unity支持两种基于物理的流行的工作流程:金属工作流(Metallic workflow)和高光反射工作流(Specular workflow)。其中,金属工作流是默认的工作流程,对应的shader为standard shader。而高光反射工作流则需要在材质的shader下拉框中选择standard (Specular setup)。Unity提供的Standard Shader允许开发者只使用一种shader来为场景中所有的物体进行着色,而不需要考虑它们是否是金属材质还是塑料材质,从而大大减少不断调整材质参数所花费的时间。

 

金属材质与非金属材质的不同:

    [1]金属材质:

           几乎没有漫反射,因为所有被吸收的光都会被自由电子立刻转化为其他形式的能量;

           有非常强烈的高光反射;

           高光反射通常是有颜色的,例如金子的高光反射为黄色。

    [2]非金属材质:

           大多数角度高光反射的强度比较弱,但在掠射角时高光反射强度反而增强,即菲涅尔现象;

           高光反射的颜色比较单一;

           漫反射的颜色多种多样。

 

需要注意的是,基于物理的渲染需要使用线性空间来进行相关计算,也就是开发者需要在Edit -> Project Setting -> Player -> Other Setting -> Color Space中选择Linear才能够实现该效果。

       Standard Shader的材质面板有许多可调节的属性,但开发者不用担心由于没有使用一些属性而会对性能有所影响。Unity在背后进行了高度优化,在生成可执行程序时,Unity会检查哪些属性没有用到,同时针对目标平台进行相应的优化。

而仅针对不同材质使用合适的属性值,尤其是一些重要的属性值,如:Albedo、Metallic、Specular是仅仅不够的,尤其是包含了复杂光照的场景。开发者还需要使用Unity提供的一系列技术,例如HDR格式的skybox、全局光照、反射探针、光照探针、HDR和屏幕后处理等技术。

1.1.3   更复杂例子

使用HDR格式的skybox可以让场景中物体的反射更加真实,有利于得到更加可信的光照效果。

除了Standard Shader外,Unity引入了一个重要的流水线——实现全局光照(Global Illumination,GI)。使用GI,场景中的物体不仅可以受直接光照的影响,还可以接受间接光照的影响。直线光照指的是直接把光照射到物体表面的光源,但在现实中,物体还会受到简介光照的影响。例如把一个球放在沙发旁边,尽管红色墙壁不发光,但是如果球靠得近,球体上会有一些由墙壁传来的间接光投射到球上。直接光和间接光可以创建更加真实的视觉效果。

当平行光面板的烘培选项(即Baking)中选择了Realtime模式,则意味着场景中受到平行光影响的物体都会进行实时的光照计算,当光源或场景中其他物体的位置、选择角度等发生变化时,场景中的光照结果也会随之变化。而如果对于移动平台来说,可以选择Baked模式,Unity会把该光源的光照效果烘培到一张光照纹理(lightingmap)中,从而不用实时计算复杂的光照。而Mix模式允许使用实时模式和烘培模式,它会把场景中的静态物体的光照烘培到光照纹理中,而运动物体产生实时光照。

间接光由GI计算出来。

反射探针的工作原理和光照探针(Light Probes)类似,它允许开发者在场景中的特定位置上对整个场景的环境反射进行采样,并把采样结果存储到每个反射结果传递给物体使用的反射纹理。如果物体周围存在多个反射探针,Unity会把从这些临近探针存储的反射结果之间进行插值,来得到平滑渐变的反射效果。例子:而如果想要实现两面镜子之间的互相反射,可以在两个反射物体的位置处各放置一个反射探针,然后随着Reflection Bounces的数值提升,可以看到反射的次数随着增加,但是如果过大或是选择实时渲染会影响性能。

 

    基于物理的渲染的过多的好处在于,可以让开发者的场景在各种光照条件下都能得到令人满意的效果,同时不需要频繁地调整材质参数。

 

使用线性空间可以得到更加真实的效果,缺点在于需要一些硬件支持来实现线性计算,一些移动平台支持不太好。而伽马空间下进行渲染计算时,由于使用了非线性的输入数据,导致很多计算都是在非线性空间下进行的,意味着得到的结果并不符合真实的物理期望。同时输出时没有考虑显示器的显示伽玛的影响,会导致渲染出的画面整体偏暗,总是和真实世界不像。

 

间接光照的计算是非常耗时的,通常不会在实时渲染中。而对于此,传统的方法是使用光线追踪,来追踪场景中每一条重要的光线的传播路径,但会非常耗时。

而Unity使用了Enlighten来让全局光照在各种平台上有不错的性能表现,而同时Enlighten也被集成到UE(虚幻引擎)中。Unity使用实时+预计算的方法来模拟场景中的光照。预计算包含了常见的光照烘培。即把光照效果提前烘培到一张光照纹理中,该光照纹理还包含了由物体反射得到的间接光照,但却无法在游戏运行时不断更新。

PBS的优点在于,只需要一个万能的Shader就可以渲染相当一大部分类型的材质,而不是使用传统的做法为每种材质写一个特定的shader,同时保证在各种光照条件下,材质都可以自然地和光照进行交互,而不需要反复调整材质参数。但是PBS通常要更复杂的光照配合,例如大量使用光照探针和反射探针,而且PBS也需要开启HDR和一些不可少的屏幕特效,例如抗锯齿等,若这些屏幕特效对游戏过于需要消耗性能,则PBS不适合当前的游戏,需要制作传统的shader来渲染游戏。

分类:

技术点:

相关文章: