
本文共 1799 字,大约阅读时间需要 5 分钟。
文章目录
UnityLab
ShaderLab 是Unity提供的编写 Unity Shader 的一种说明性语言。
Unity Shader 的基础结构
Shader "ShaderName" { // Shader 的名字 Properties { // 属性 } SubShader { // 显卡 A 使用的子着色器 } SubShader { // 显卡 B 使用的子着色器 } Fallback "VertexLit"}
Properties 语义块
Properties 语义块的作用仅是为了让这些属性可以出现在材质面板中。
SubShader
每一个Unity Shader 文件可以包含多个SubShader语义块,但最少要有一个。当Unity需要加载这个Unity Shader时,Unity会扫描所有的SubShader语义块,然后选择第一个能够在目标平台上运行的SubShader。如果都不支持的话,Unity就会使用Fallback语义指定的Unity Shader。
Unity提供这种语义的原因在于,不同的显卡具有不同的能力。例如,一些旧的显卡仅能支持一定数目的操作指令,而一些更高级的显卡可以支持更多的指令数,那么我们希望在旧的显卡上使用计算复杂度较低的着色器,而在高级的显卡上使用计算复杂度较高的着色器,以便提供更出色的画面。
SubShader { // 标签(可选) [Tags] // 状态(可选) [RenderSetup] Pass { } // Other Passes}
Pass
每个Pass定义了一次完整的渲染流程,但如果Pass的数目过多,往往会造成渲染性能的下降。因此,我们应尽量使用最小数目的Pass。
状态和标签同样可以在Pass声明。但SubShader中的一些标签设置和Pass中的标签是不一样的。而对于状态设置来说,其使用的语法是相同的。
但是,如果我们在SubShader进行了这些设置,那么将会用于所有的Pass。
常见的渲染状态设置选项:

Pass { [Name] [Tags] [RenderSetup] // Other code}
我们可以在Pass中定义该Pass的名称,例如:
Name "MyPassName"
这样,我们可以用ShaderLab的UsePass
命令来直接使用其他Unity Shader中的Pass。例如:
UsePass "MyShader/MYPASSNAME"
这样可以提高代码的复用性。
需要注意的是,由于Unity内部会把所有Pass的名称转换成大写字母的表示,因此,在使用UsePass命令时必须使用大写形式的名字。
Tags
SubShader的标签(Tags)是一个键值对(Key/Value Pair),它的键和值都是字符串类型。这些键值对是SubShader和渲染引擎之间的沟通桥梁。它们用来告诉Unity的渲染引擎: SubShader我希望怎样以及何时渲染这个对象。
Tags { "TagName1" = "Value1" "TagName2" = "Value2" }
SubShader的标签类型

表面着色器
表面着色器(Surface Shader)是Unity自己创造的一种着色器代码类型。
它需要的代码量很少,Unity在背后做了很多工作,但渲染的代价比较大。
它在本质上和下面要讲到的顶点/片元着色器是一样的。当给Unity提供一个表面着色器的时候,它在背后仍旧把它转换成对应的顶点/片元着色器。
表面着色器是Unity对顶点/片元着色器的更高一层的抽象。Unity为我们处理了很多光照细节,使得我们不需要再关注这些。
实例:

CGPROGRAM 和 ENDCG 之间的代码是使用 CG/HLSL 编写的。这里的 CG/HLSL 是 Unity 经封装后提供的。
顶点 / 片元 着色器
示例:

固定函数着色器
一些较旧的设备不支持可编程管线着色器,这时候我们就要用固定函数着色器(Fixed Function Shader)来完成渲染。
示例:

其他文章
下一章:
专题文章:
发表评论
最新留言
关于作者
