ShaderLab
真正的Shader需要开发者与很多文件与设置打交道,才能呈现出想要的效果;而Unity Shader为我们提供了一层抽象,ShaderLab是Unity提供的一种专门为Unity Shader服务的语言。在Unity Shader的帮助下,开发者只需要使用ShaderLab编写Unity Shader文件,就可以完成所有的工作。
Unity Shader的结构
Unity为我们提供了如下几种Unity Shader模板
Standard Surface Shader: 会创建一个包含标准光照模型的表面着色器模板。
Unlit Shader: 会创建一个不含光照的基本顶点/片元着色器。
Image Effect Shader: 会为我们实现各种屏幕后处理效果提供一个模板。
Compute Shader: 会产生一种特殊的Shader文件,这类Shader旨在利用GPU的并行性来进行一些与常规渲染流水线无关的计算。
Ray Tracing Shader: 会创建一个光线追踪着色器。
下面以顶点/片元着色器(Unlit Shader)为例讲解Unity Shader的基本结构。
// 当前Shader的名称,斜杠可以控制当前Shader显示在材质面板下拉列表的位置
Shader "Unlit/MyShader"
{
// 属性块
Properties
{
//....
}
SubShader
{
//标签(key-value),可选
Tags {}
// 渲染设置,可选
Cull off
//....
Pass
{
Name "MyPass"
Tags{}
// 渲染设置 也可以在Pass通道中定义
// .....
// CG语言代码,主要是顶点/片元着色器
CGPROGRAM
// ....
ENDCG
}
}
Fallback off // "name"/off 当上面的SubShader都无法执行时,执行此语句
}
Properties
Properties语义块支持的属性类型如下:
Properties
{
_Int("Int",int) = 2
_Float("Float",float) = 1.5
_Range("Range",Range(0.0,2.0)) = 1.0
_Color("Color",Color) = (1,1,1,1)
_Vector("Vector",Vector) = (1,2,3,4)
_MainTex ("Texture", 2D) = "white" {}
_Cube("Cube",Cube) = "white"{}
_3D("3D",3D) = "black"{}
// 相当于变量,会显示在Inspector面板中
// 结构: 变量名(显示名称,类型) = 默认值
}
对于属性块(Properties)中声明的变量,可以在材质面板进行调整(需要先将Shader指定给一个材质),材质面板中显示的变量名是引号中的名称,如果要再Shader中访问这些变量,可以通过变量名访问。
SubShader
每一个Unity Shader都必须包含至少一个SubShader语义块。当游戏运行在不同平台上时,Unity会扫描所有的SubShader,并选择第一个能够运行的SubShader。如果都无法运行,则会调用Fallback语义指定的Unity Shader。
SubShader {
// 可选
[Tags]
// 可选
[RenderSetup]
// 必选,可以有多个
Pass{}
// 可选
[Fallback]
}
Tags
SunShader的标签(Tags)是一个键值对,且键和值都是字符串类型。它用来告诉Unity该怎样及如何渲染这个对象。
SubShader支持的标签类型如下:
Tags {
"Queue"="Transparent" //Queue 渲染顺序
"RenderType"="Opaque" //RenderType 渲染类型(着色器替换功能)
"DisableBatching"="True" //禁用批处理
"ForceNoShadowCasting"="True" //是否投射阴影
"IgnoreProjector"="True" //忽略Projector影响(通常用于透明物体)
"CanUseSpriteAltas"="False" //是否用于图片的Shader(通常用于UI)
"PreviewType"="Plane" //用作Shader面板预览的类型
}
RenderSetup
用于设置显卡的各种状态,例如是否开启混合/深度测试等。
常见的渲染状态设置选项如下:
Cull off // 设置剔除哪个面 [off(正反两面都渲染)/back/front]
ZTest Always // 设置深度测试使用的函数 [Always/Less/Greater/LEqual/GEqual/Equal/NotEqual]
Zwrite off // 设置是否开启深度写入 [on/off]
Blend [SrcFactor(源)] [DstFactor(目标)] //开启并设置混合模式
LOD 100 // 细节层次,unity引擎会根据不同的LOD值在使用不同的SubShader
Pass
每个Pass定义了一次完整的渲染流程,但如果Pass的数目过多,往往会造成性能下降。
Pass {
[Name]
[Tags]
[RenderSetup]
// CG代码
//....
}
Name语句可以设置当前Pass的名称,可以在其他Unity Shader中使用UsePass命令来使用这个Pass,需要注意的是,使用UsePass命令时必须使用大写形式的名字。
用法如下:
Name "MyPass"
Pass同样可以设置标签,但不同于SunShader的标签,这些标签也用于告诉引擎怎样渲染这个物体。
Pass中使用的标签类型如下:
Tags{
"LightMode"="ForwardBase"// 定义该Pass通道在Unity渲染流水中的角色
"RequireOptions"="SoftVegetation"// 满足某些条件时才渲染该Pass通道
}
SubShader的渲染状态设置同样适用于Pass。
Fallback
当前Unity Shader中的SunShader都无法运行时,调用Fallback语句,一般用于指定一个最基础的Shader。
用法如下
Fallback "name"
或
Fallback off