Tags标签
表面着色器可以被若干的标签(tags)所修饰,而硬件将通过判定这些标签来决定什么时候调用该着色器。
语法:Tags { “TagName1” = “Value1” “TagName2” = “Value2” … }
就是 Tags 语法块内带有若干键值对项(理论上可有很多很多个这种键值对)。
需要注意一点 它只能写在 Subshader 语句块里面,不能写在 Pass 语句块里面
案例:
Shader "Custom/Diffuse Texture" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
比如我们的例子中SubShader的第一句:
Tags { "RenderType"="Opaque" }
告诉了系统应该在渲染非透明物体时调用我们。
Unity定义了一些列这样的渲染过程,与RenderType是Opaque相对应的显而易见的是”RenderType” = “Transparent”,表示渲染含有透明效果的物体时调用。
在这里Tags其实暗示了你的Shader输出的是什么,如果输出中都是非透明物体,那写在Opaque里;如果想渲染透明或者半透明的像素,那应该写在Transparent中。
另外比较有用的标签还有:
"IgnoreProjector"="True"
(不被Projectors影响), "ForceNoShadowCasting"="True"
(从不产生阴影) "Queue"="xxx"
(指定渲染顺序队列)。
这里想要着重说一下的是Queue这个标签,如果你使用Unity做过一些透明和不透明物体的混合的话,很可能已经遇到过不透明物体无法呈现在透明物体之后的情况。这种情况很可能是由于Shader的渲染顺序不正确导致的。
Queue
Queue指定了物体的渲染顺序,预定义的Queue有:
- Background - 对应数值为 1000,最早被调用的渲染,用来渲染天空盒或者背景
- Geometry - 对应数值为 2000,这是默认值,用来渲染非透明物体(普通情况下,场景中的绝大多数物体应该是非透明的)
- AlphaTest - 对应数值为 2450,用来渲染经过Alpha Test的像素,单独为AlphaTest设定一个Queue是出于对效率的考虑
- Transparent - 对应数值为 3000,以从后往前的顺序渲染透明物体
- Overlay - 对应数值为 4000,用来渲染叠加的效果,是渲染的最后阶段(比如镜头光晕等特效)
渲染顺序的示意图如下:
前面提到虽然 Queue 内部是整型数值,但是写 shader 的时候不能给它指定整型数值,那要是前置给它指定为整型数值会怎么样?
答案是:会被忽略,使用默认的值,也就是 Geometry。同样的,随便填写的值也是会被忽略并使用默认值代替。 比如 asd1123
。
还有 Shaderlab 还对上面五类做了延伸,让他们 支持加减法。比如想让对象在 Background 之后 Geometry 之前渲染,我们可以这么写:
Tags { “Queue” = “Geometry-1”}
这里有几点比较重要:
-
Geometry-1
中间不能有空格 - 这个语法是整型数值的加减法。
Geometry-1
和Background+999
得到的结果是一样的,因为 2000 - 1 = 1000 + 999。
我们在 Unity 编辑器里面选中 shader 文件,然后从 Inspector 里查看 Shader 的 Render queue 属性值,如下图: