stonstad 发表于 2023-1-11 17:26

《Unity Shader入门精要》笔记(三十六)

本文为《Unity Shader入门精要》第十八章《基于物理的渲染》的第二节内容《Unity 5的Standard Shader》。
本文相关代码,详见:

原书代码,详见原作者github:
<hr/>
虽然Unity 5对我们来说是相当老的版本了,但是其核心思路变化不大,所以这一节的内容对我们来说还是很有学习价值的。

Unity 5中默认的着色器——Standard Shader,它使用了基于物理的渲染。

Unity支持两种流行的基于物理的工作流程:

[*]金属工作流(Metallic workflow)
默认的工作流程,对应Shader——Standard Shader。

[*]高光反射工作流(Specular workflow)
如果想使用该工作流,需要在材质的Shader下拉框中选择Standard (Specular setup)。

注意:
通常,使用不同的工作流可以实现相同的效果,只是它们的参数不同。
金属工作流不是只能模拟金属类型的材质,其名字来源于它定义了材质表面的金属值(0:非金属,1:金属);
高光反射名字来源于它直接指定表面的高光反射颜色等,这个颜色在金属工作流中需要由漫反射颜色和金属值衍生而来。

下面的内容用Standard Shader来统称Standard和Standard(Specular setup)着色器。

1. 它们是如何实现的

Standard和Standard (Specular setup) Shader依赖于CGIncludes文件夹中定义的一些头文件,以下是一些常用的头文件及其主要用处:



Standard和Standard (Specular setup) Shader代码结构基本相同,都定义了两个SubShader:

[*]第一个SubShader
计算更复杂,主要针对非移动平台(通过#pragma exclude_renderers gles代码排除GLES平台),定义了前向渲染路径和延迟渲染路径使用的Pass,以及用于投射阴影和提取元数据的Pass。

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

Standard和Standard (Specular setup) Shader的最大不同在于,在设置BRDF的输入时使用不同的函数来设置各个参数:

[*]基于金属工作流的Standard Shader使用MetallicSetup函数;
[*]基于高光反射工作流的Standard (Specular setup) Shader使用SpecularSetup函数。
以上两个函数均可在UnityStandardCore.cginc文件中找到定义。

Standard Shader用于前向渲染路径的典型实现:



两个Pass的代码大体相同,只是ForwardBase Pass进行了更多的光照计算,这些计算在整个渲染过程中计算一次即可,无需再ForwardAdd Pass中再次计算。

2. 如何使用Standard Shader

金属材质:

[*]几乎没有漫反射(光被自由电子转为其他能量);
[*]有非常强烈的高光反射;
[*]高光反射通常有颜色(如:金子的反光颜色为黄色);

非金属材质:

[*]大多数角度高光反射的强度比较弱,但掠射角时高光反射强度反而会增强——菲涅尔现象;
[*]高光反射的颜色比较单一;
[*]漫反射颜色多种多样;

真实的材质大多混合了上面这些特性,Unity提供的工作流是为了更加方便让我们针对以上特性来调整材质效果。

Unity官方提供的金属工作流和高光反射工作流使用的参数属性值:



原书资源场景Scene_18_2中给出了一个简单的案例,展示了金属和非金属材质的区别:



因为基于物理的渲染需要使用线性空间进行相关计算,所以需要在Edit-Project Settings-Player-OtherSettings-Color Space中渲染Linear:



金属工作流和非金属工作流的材质面板:



金属工作流中:

[*]Albedo
它定义了物体的整体颜色,也就是视觉上的物体颜色。从亮度看,非金属材质的亮度范围通常在50~243,而金属材质的亮度在186~255。我们也可以直接使用一张纹理作为材质的Albedo值。

[*]Metallic
它定义物体表面看起来更像金属还是更像非金属。它可以使用一张纹理采样得到表面的Metallic值,纹理的R通道对应了该值。0表示非金属,1表示金属。

[*]Smoothness
上一个属性Metallic的附属值,定义了从视觉上看该表面的光滑程度。如果Metallic属性使用一张纹理,则该纹理的A通道对应了表面的Smoothness值。

高光反射工作流使用的面板和上面的基本相同,区别在于:

[*]Albedo
使用的含义不同,它定义了表面的漫反射强度。对于非金属材质,它就是视觉上认为的物体颜色;但对于金属,它的值非常接近黑色(金属材质几乎不存在次表面散射)。

[*]Specular
使用Specular代替上面的Metallic属性。Specular属性定义了表面高光反射强度。非金属材质使用一个灰度值范围在0~55的深灰色作为Specular值,表明非金属材质的高光反射较弱;而金属材质则使用视觉上认为的该金属的颜色作为它的Specular值。

[*]Smoothness
Specular的附属值,定义了视觉上看该表面的光滑程度,同样可以使用一张纹理对Specular复制,纹理的RGB通道对应了Specular属性值,A通道对应了Smoothness属性值。

上面属性都属于材质面板的Main Maps部分,除提到的疏星外,还包含了其他属性,如:切线空间下的法线纹理、遮挡纹理、自发光纹理等。
Main Maps下面还有一个Secondary Maps部分,用来定义额外的细节信息,这些细节通常会直接绘制在Main Maps上面,为材质提供更多的为表面或细节表现。

材质面板上的Render Mode选项,Standard Shader支持4种渲染模式:

[*]Opaque
用于渲染最常见的不透明物体,也是默认的渲染模式。

[*]Transparent
用于渲染像玻璃这样的材质。此模式下,Albedo属性的A通道用于控制材质的透明度。

[*]Cutout
此模式下,Albedo属性中纹理的A通道会成为一个掩码纹理,它的子属性Alpha Cutoff将是透明度测试时使用的阈值。

[*]Fade
与Transparent模式类似,不同之处:Transparent模式下,当材质的透明度不断降低时,反射仍然会被保留,而Fade模式下,材质的算有渲染效果都将逐渐淡出。

Unity在背后进行了高度优化,对于一些没有使用的属性,Unity在生成可执行程序时会进行检测,从而不会让没用到的属性影响性能。

想要得到可信度更高的渲染结果,需要对不同的材质使用合适的属性值,尤其一些重要的属性值,如:Albedo、Metallic、Specular。
想让整体效果更令人满意,尤其是包含复杂光照的场景,仅这些远远不够,Unity提供了一些重要的技术,如:HDR格式的Skybox、全局光照、反射探针、光照探针、HRD和屏幕后处理等。

以上是本次笔记的所有内容,下一篇笔记我们将结合一个更复杂的例子来学习更加复杂的基于物理的渲染。

<hr/>
写在最后

本文内容会同步发在笔者的公众号上,欢迎大家关注交流!
公众号:程序员叨叨叨(ID:i_coder)
页: [1]
查看完整版本: 《Unity Shader入门精要》笔记(三十六)