文章

UnityShade入门精要(14`基于物理的渲染)

基于物理的渲染

PBR光照模型

为了更加真实的渲染效果,使用基于物理的渲染技术 (Physically Based Rendering),

一个PBR光照模型,是否基于物理的,可以根据三个特性来判断:它是否满足能量守恒 (energy conservation)表面反射的不能超过入射的光能,微平面理论(表面实际是由许多人哏看不到的微面元组成的),基于物理的BRDF

光线从发光物发射出来,经过物体的吸收和散射(反射,折射) ,传入人眼,

次表面散射SSS:诸如皮肤,蜡烛等材质,光线在折射入物体内部会再次散射或吸收,一些光会从不同于入射点的位置从物体内部再次射出,从而让物体表面的明暗过渡更加自然,小的表面细节变得看不清,往往引起微弱的倾向红色的颜色偏移,

但是目前我们不会考虑SSS,这部分仅仅由常量(BRDF中的漫反射部分)代替

双向反射分布函数 (BRDF)

我们通常使用辐射度量学量化光,可以把对物体入射的光线称为入射辐射功率,如果要得到出射辐射功率,用BRDF来求得,

各项同性(isotropic)材质:绕着表面法线旋转入射方向或观察方向并不会影响结果,反之各项异性(anisotropic)

BRDF:表示某方向入射 能量,经过BRDF后,向某观察方向反射多少能量

反射等式 == 出射辐射率:所有半球方向入射的能量经过BRDF反射到观察方向的能量

渲染方程(PBR光照模型):物体自发光能量 + 所有半球方向入射的能量经过BRDF反射到观察方向的能量

对于BRDF通常分解为漫反射和镜面部分描述它

BRDF漫反射部分

最简单的BRDF漫反射模型——兰伯特: cdiff 漫反射颜色 / pai (假设漫反射在所有方向上的强度都是相同的)

BRDF镜面反射部分

1735008229334

D(h)是法线分布函数,有多少个微小平面,会将光线反射到人眼,即反射光线 == h半程方向

G(l,v,h)是几何函数,表示在微平面中,有多少反射光线会被遮挡,不会被看到

F菲涅尔反射 ,表示了反射光线占入射光线的比率

4(n·l)(n·v)是用于校正从微面元的局部空间到整体宏观表面数扯差异的校正因子

其中DGF又有各自的多种模型实现,比如D的GGX、 Beckmann模型等。G的Smith 模型,F的 Schlick等

Standard Shader

幸运的是,在Unity 中我们不需要自己在shader 中实现上面的公式, Unity 已经为我们提供了现成的基于物理着色的shader, 也就是Standard Shader,它上面有很多uniform参数供我们调整

Unity 支持两种基于物理的工作流(使用的参数不同,实现相同的效果),金属工作流 (Metallicwork.flow) 和高光反射工作流 (Specular work.flow)

它们都定义了两个 SubShader, 第一个SubShader 使用的计算更加复杂,主要针对非移动台),并定义了前向渲染路径和延迟渲染路径使用的 Pass, 以及用于投射阴影和提取元数据的Pass

第二个SubShader定义了 4个 Pass, 其中两个Pass用于前向渲染路径, 一个 Pass 用于投射阴影, 另一个 Pass 用于提取元数据,该 SubShader 主要针对移动平台

使用 Standard Shader(PBR着色器)

金属材质 vs.非金属材质

1735008262567

但真实的材质大多混合了上面的这些特性, 但如果想要正确的效果,需要Project Setttings–Player-Other Settings-Color Space 中选择Linear,这是因为基于物理的渲染需要使用线性空间

Albedo 定义了物体的整体颜色,非金属材质的亮度范围通常在50——243 之间,,而金属材质的亮度一般在186 —— 255 之间,也可以直接使用一张纹理作为材质的Albedo值

Metallic, 它定义了该物体表面看起来是否更像金属或非金属,同样,我们也可以使用一张纹理来采样得到表面的Metallic值,1表明完全是金属材质

Smoothness,定义了从视觉上来看该表面的光滑程度,1表示完全光滑,0表示粗糙

高光反射工作流使用的面板和上述金属工作流使用的基本相同,Albedo反射率属性定义了表面的漫反射强度,使用 Specular代替了上述的 Metallic 属性,定义了表面的高光反射强度

以上这些都属千材质面板中的MainMaps部分,MainMaps还包含了其他材质屈性,例如,切线空间下的法线纹理、遮挡纹理、自发光纹理等,还有一个Secondary Maps 的属性部分, 这个部分的属性是用来定义额外的细节信息,

我们还可以为 Standard Shader 选择它使用的渲染模式, 即材质面板上的Render Mode选项。Standard Shader支持4种渲染模式,分别是Opaque(最常见的不透明物体)、Cutout( A 通道会成为一个掩码纹理)、Fade(该材质的所有渲染效果都会逐渐从屏幕上淡出)和Transparent(透明物体)

物体光照来源

一个物体的光照来源包括:自发光(作为光源物体),环境光(各方向基本均匀的微弱光线,可以看作是全局光照的简化模型),内部散射(漫反射),外部散射(镜面反射),全局光照(Global Illumination, GI) (直接光照,间接光照),环境映射(特指于从cubmap获取的光线,反射和折射)

以上都由近似光照模型计算,每个部分都有自己的颜色和强度值

实例

首先设置HDR格式的Cubemap作为Skybox,调整旋转

可以选择环境光照的来源,比如来源于skybox天空盒,还是使用渐变值,亦或是某个固定的颜色,还可以设置环境光照的强度(Ambient Intensity 参数),

反射源 (Reflection Source选项)以及反射强度

调整平行光的颜色,方向等属性(位置不影响平行光),mode的烘培Baking的 Realtime模式意味着实时的光照计算,baked模式把该光源的光照效果烘焙到一张光照纹理 (lightmap) 中, 这样我们就不用实时为物体计算复杂的光照,Mix模式则允许我们混合使用实时模式(静态物体)和烘焙模式(动态物体)

光源面板中的BounceIntensity 参数可以让我们调节这些间接光照的强度

反射探针(ReflectionProbes)

对于镜子,玻璃等物体,通常会用环境映射(从cubmap采样)模拟反射特性,但是通常并没有随着物体位置变化而发生环境变化。一种解决办是可以在脚本中控制何时生成从当前位翌观察到的Cubemap(如之前运行前生成的cubmap),但更方便的方法是反射探针

反射探针的工作原理和光照探针 (LightProbes) ,它允许我们在场景中的特定位置上对整个场景的环境映射(反射)进行采样,当物体从这些探针附近经过时,会把从这些邻近探针存的反射结果传递给物体使用的反射纹理,来得到平滑渐变的反射效果

反射探针同样有3种类型:

  • Baked, 这种类型的反射探针是通过提前烘焙来得到该位置使用 Cubemap 的,
  • Realtime, 这种类型则会实时更新当前的 Cubemap, 并且不受静态物体还是动态物体的影响
  • Custom, 这种类型的探针既可以让我们从编辑器中烘焙它,也可以让我们使用一个自定义的Cubemap 来作为反射映射,但自定义的 Cubemap不会被实时更新。

互相反射 (interreflections):两面互相面对面的镜子,它们会一直相互反射光线,直到光线被完全吸收,表现为不仅会反射自己对面的那面镜子,也会反射那面镜子里反射的图像,这是传统的反射方法所无法实现的,但是反射探针让这种效果变成了可能

1735026655358

通过改变的Reflection Bounces参数来控制物体之间这样来回反射的次数

本文由作者按照 CC BY 4.0 进行授权
本页总访问量