ShaderLab: Culling & Depth Testing
https://docs.unity3d.com/Manual/SL-CullAndDepth.html
####Cull 表面剔除
Cull Back | Front | Off
ShaderLab | Desc | 说明 |
---|---|---|
Off | Disables culling - all faces are drawn. Used for special effects. | 不剔除 |
Back | Don’t render polygons facing away from the viewer (default). | 剔除背面(内表面) |
Front | Don’t render polygons facing towards the viewer. Used for turning objects inside-out. | 剔除正面(外表面) |
ZWrite
ZWrite On | Off
Controls whether pixels from this object are written to the depth buffer (default is On).
ZWrite可以取的值为:On/Off,默认值为On,代表是否要将像素的深度写入深度缓存中(同时还要看ZTest是否通过)。
ZTest
ZTest Less | Greater | LEqual | GEqual | Equal | NotEqual | Always
Controls whether pixels from this object are written to the depth buffer (default is On).
ZTest可以取的值为:Greater/GEqual/Less/LEqual/Equal/NotEqual/Always/Never/Off
,默认值为LEqual,ZTest Off 等同于 ZTest Always,代表通过比较深度来更改颜色缓存的值。例如当取默认值的情况下,如果将要绘制的新像素的z值小于等于深度缓存中的值,则将用新像素的颜色值更新深度缓存中对应像素的颜色值。
需要注意的是,当ZTest取值为Off时,表示的是关闭深度测试,等价于取值为Always,而不是Never!Always指的是直接将当前像素颜色(不是深度)写进颜色缓冲区中;而Never指的是不要将当前像素颜色写进颜色缓冲区中,相当于消失。
还是有点懵,再探讨探讨~~
- 什么是深度?
深度其实就代表该像素在世界空间中距离摄像机的距离。离相机越远,深度值(Z)越大;
- 什么是深度缓存
深度缓存中存储着准备要绘制在屏幕上的像素点
的深度值。如果启用深度缓冲区,在绘制每个像素之前,会把该像素的深度值和深度缓冲区的深度值进行比较。如果新像素深度值 < 深度缓存深度值,则新像素值取代本来该点的值,缓冲区的深度值也替换成新像素点的深度值;反之,新像素值被遮挡,其颜色值和深度将被丢弃。
- 什么是深度测试
深度测试默认情况是将要绘制的新像素的z值与深度缓冲区对应位置的z值的进行比较,如果比深度缓存中的值小,就用新像素的颜色值更新深度缓冲中对应像素的颜色值。
- 为什么需要深度
如果不使用深度测试,后绘制的物体会把先绘制的物体覆盖掉。有了深度缓冲后,绘制顺序就不那么重要,可以按照远近(z值)来正常显示。
结论:
- ZTest通过,ZWrite为On:写入深度缓冲区,写入颜色缓冲区;
- ZTest通过,ZWrite为Off:不写深度缓冲区,写入颜色缓冲区;
- ZTest失败,ZWrite为On:不写深度缓冲区,不写颜色缓冲区;
- ZTest失败,ZWrite为Off:不写深度缓冲区,不写颜色缓冲区;
验证:
测试环境:
White Cube 坐标(1.5,0.5,1)
Blue Cube 坐标(0,0,0)
Cemera 坐标(0, 0 -10)
Shader "Custom/ZTestBlue"
{
Properties
{
_MainTex("Base (RGB)", 2D) = "white" {}
}
SubShader
{
Tags
{
"RenderType" = "Opaque"
"Queue" = "Geometry+200"
}
LOD 200
ZWrite Off
ZTest Off
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"
}
Shader "Custom/ZTestWhite"
{
//同上(调整ZWrite和ZTest进行测试)
}
结果 :
注意ZWrite默认值为On,ZTest默认值为LEqual。
"//ZWrite Off" == "ZWrite On"
"//ZTest Off" == "ZTest LEqual"
"ZTest Off" == "ZTest Always"
BlueZWrite | BlueZTest | WhiteZWrite | WhiteZTest | 运行结果 | 分析 |
---|---|---|---|---|---|
//Off | //Off | //Off | //Off | 头像离相机近ZTest通过,ZWrite为On,颜色值写入缓存,深度值写入缓存;白色值ZTest不通过颜色不写入,深度值也不写入,所以头像在前。 | |
Off | Off | Off | Off | 头像ZTest通过,颜色值写入缓存,ZWrite为Off,深度值不写入;白色ZTest为Always所以颜色值写入,ZWrite为Off深度值不写入,所以交汇部分白色。 | |
Off | Off | //Off | //Off | 头像ZTest通过,颜色值写入缓存,ZWrite为Off,深度值不写入;白色ZTest通过所以颜色值写入,ZWrite为On深度值写入,所以交汇部分白色。 | |
//Off | //Off | Off | Off | 头像ZTest通过,颜色值写入缓存,ZWrite为On,深度值写入;白色ZTest通过所以颜色值写入,ZWrite为Off深度值不写入,所以交汇部分白色。 |
其他类推,就不一一列举了。