Unity Shader 基础

Unity Shader 基础

此文章收录于我主页顶置的:Unity Shader入门精要文章目录,点击即可跳转。

概括:在Unity中,我们要将材质和Shader结合起来才能够达到需要的效果
Unity Shader本质上是一个ShaderLab文本文件,在硬盘中以 .Shader 作为文件后缀的一种文件,在该文件里面显示Unity在背后为该表面着色器生成的顶点/片元着色器。

Unity 中的 Shader
在Unity5.2及以上的版本中,Unity一共提供了4种Unity Shader模板供我们选择:
(1)Standard Surface Shader:会产生一个包含了标准光照模型的表面着色器模板。
(2)Unity Shader:产生一个不包含光照(但包含雾效)的基本顶点/片元着色器。
(3)Image Effect Shader:为我们实现各种屏幕后处理效果提供一个基本模板。
(4)Computer Shader:产生一种特殊的Shader文件,这类Shader旨在利用GPU的并行性来进行一些与常规渲染流水线无关的计算。

一个单独的Unity Shader是无法发挥单独的作用的,必须要于材质结合起来!                                                                          

Unity Shader 基础_第1张图片
在Unity 5.2版本中,Unity Shader的导入设置面板如图3.4所示。在该面板上,我们可以在Default Maps中指定该Unity Shader使用的默认纹理。
我们可以通过单击Show generated code 按钮来打开一个新的文件, 在该文件里将显示Unity在背后为该表面着色器生成的顶点片元着色器。这可以方便我们对这些生成的代码进行修改( 需要复制到一个新的Unity Shader 中才可保存)和研究。同样地,如果该UnityShader是-个固定函数着色器,在Fixedfunction的后面也会出现一个Showgenerated code按钮,来让我们查看该固定函数着色器生成的顶点/片元着色器。
Unity Shader 基础_第2张图片
Compile and showcode下拉列表可以让开发者检查该Unity Shader针对不同图像编程接口( 例如OpenGL、D3D9、D3D11等)最终编译成的Shader代码,如图3.5所示。直接单击该按钮可以查看生成的底层的汇编指令。我们可以利用这些代码来分析和优化着色器。

ShaderLab
Unity Shader 基础_第3张图片

在Unity中,所有的Unity Shader 都是使用ShaderLab来编写的。ShaderLab是Unity提供的编写Unity Shader的一一种说明性语言。它使用了一些嵌套在花括号内部的语义(syntax) 来描述一个Uniy Shader 文件的结构。这些结构包含了许多渲染所需的数据,例如Properies语句块中定义了着色器所需的各种属性,这些属性将会出现在材质面板中。从设计上来说,ShadeLab 类似于CgX和DirerD Effects(.FX)语言,它们都定义了要显示一个材质所需的所有东西,而不仅仅是着色器代码

Unity Shader的结构
1.Unity的命名
修改Unity Shader的名字时,可以通过添加 / (斜线) 的方式控制其在Unity Shader中出现的位置。
Unity Shader 基础_第4张图片
2.材质和Unity Shader的桥梁:Property(属性)
Property语义中包含了一系列属性,这些属性将会出现在材质面板中。如果我们需要在Unity Shader中访问它们,就需要使用每个属性的名字。

3.重量级成员: SubShader

每一个Unity Shader文件可以包含多个SubShader语义块,但最少要有一个当Unity需要加载这个Unity Shader时,Unity会扫描所有的SubShader语义块,然后选择第一个能够在目标平台上运行的SubShader。如果都不支持的话,Unity 就会使用Fallback语义指定的Unity Shader.Unity 提供这种语义的原因在于,不同的显卡具有不同的能力。例如,一些旧的显卡仅能支持一定数目的操作指令,而一些更高级的显卡可以支持更多的指令数,那么我们希望在旧的显卡上使用计算复杂度较低的着色器,而在高级的显卡上使用计算复杂度较高的着色器,以便提供更出色的画面。

SubShader中定义了一系列Pass以及可选的状态([RenderSetup]) 和标签([Tags]) 设置。每个Pass定义了一次完整的渲染流程,但如果Pass的数目过多,往往会造成渲染性能的下降

状态设置:ShaderLab提供了一系列渲染状态的设置指令,这些指令可以设置显卡的各种状态,例如是否开启混合/深度测试等。

SubShader的标签
SubShader的标签(Tags) 是一个键值对 (Key/Value Pair),它的键和值都是字符串类型。这些键值对是SubShader 和渲染引擎之间的沟通桥梁。它们用来告诉Unity 的渲染引擎:我希望怎样以及何时渲染这个对象。(具体情况查表)

Pass语义
首先我们可以在Pass中定义Pass的名称,通过这个名称,我们可以使用ShaderLab的UsePass命令来直接使用其他Unity Shader 中的Pass。

需要注意的是,由于Unity 内部会把所有Pass的名称转换成大写字母的表示,因此,在使用UsePass命令时必须使用大写形式的名字

Pass同样可以设置标签,这些标签不同于SubShader的标签,这些标签也是告诉我们如何去渲染引擎我们希望怎样来渲染物体。Unity Shader还支持一些特殊的Pass,以便进行代码复用或实现更加复杂的效果。
UsePass:复用其它Unity Shader中的Pass。
GrabPass:抓取屏幕并将结果存储在一张纹理中,以用于后续的Pass处理。

留一条后路:FallBack
紧跟在各个SubShader语义块后面的,可以是一个Fallback 指令。它用于告诉Unity,“如果上面所有的SubShader在这块显卡上都不能运行,那么就使用这个最低级的Shader吧

Fallback还会影响阴影的投射。在渲染阴影纹理时,Unity 会在每个Unity Shader 中寻找一个阴影投射的Pass。通常情况下,我们不需要自己专门实现一个Pass,这是因为Fallback使用的内置Shader中包含了这样一个通用的Pass。因此,为每个Unity Shader正确设置Fallback是非常重要的。

4.Unity Shader的形式
在Unity中骂我们会用到以下三种形式来编写Unity Shader,而不管使用那种形式,真正的Shader代码都需要包含在ShaderLab语义中。

**表面着色器:**是Unity自己创造的一种着色器类型,它需要的代码量很少,Unity在背后做了很多工作,但渲染的代价比较大,它在本质上和顶点着色器、片元着色器是一样的

**顶点/片元着色器:**在Unity中我们可以使用Cg/HLSL语言来编写顶点/片元着色器,它们更加复杂,但是灵活性也更高。
顶点/片元着色器是写在Pass语义块内,而非SubShader内的。原因是,我们需要自己定义每个Pass需要使用的Shader代码

**固定函数着色器:**针对于比较旧的设备,它们不支持可编程管线着色器,这类着色器往往只能够实现一些比较简单的效果。对于固定函数着色器来说,我们需要完全使用ShaderLab的语法来编写,而非Cg/HLSL。

选择哪种Unity Shader的形式

1.除非你有非常明确的需求必须要使用固定函数着色器,例如需要在非常旧的设备上运行你的游戏(这些设备非常少见),否则请使用可编程管线的着色器,即表面着色器或顶点片元着色器。

2.“如果你想和各种光源打交道, 你可能更喜欢使用表面着色器,但需要小心它在移动平台的性能表现。

3.如来能好源便用的先限数目非营小、侧如只有一个平行光。那么使用顶点/片元着色器是一个更好的选择。

4.最重要的是,如果你有很多自定义的道染效果,那么请选择顶点/片元着色器。

你可能感兴趣的:(Unity,Shader,入门精要,Unity,Shader)