【ShaderLab学习】Cull ZWrite ZTest理解

ShaderLab: Culling & Depth Testing

https://docs.unity3d.com/Manual/SL-CullAndDepth.html

在这里插入图片描述

####Cull 表面剔除

Cull Back | Front | Off
ShaderLabDesc说明
OffDisables culling - all faces are drawn. Used for special effects.不剔除
BackDon’t render polygons facing away from the viewer (default).剔除背面(内表面)
FrontDon’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值)来正常显示。

结论:
  1. ZTest通过,ZWrite为On:写入深度缓冲区,写入颜色缓冲区;
  2. ZTest通过,ZWrite为Off:不写深度缓冲区,写入颜色缓冲区;
  3. ZTest失败,ZWrite为On:不写深度缓冲区,不写颜色缓冲区;
  4. 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"
BlueZWriteBlueZTestWhiteZWriteWhiteZTest运行结果分析
//Off//Off//Off//Off在这里插入图片描述头像离相机近ZTest通过,ZWrite为On,颜色值写入缓存,深度值写入缓存;白色值ZTest不通过颜色不写入,深度值也不写入,所以头像在前。
OffOffOffOff在这里插入图片描述头像ZTest通过,颜色值写入缓存,ZWrite为Off,深度值不写入;白色ZTest为Always所以颜色值写入,ZWrite为Off深度值不写入,所以交汇部分白色。
OffOff//Off//Off在这里插入图片描述头像ZTest通过,颜色值写入缓存,ZWrite为Off,深度值不写入;白色ZTest通过所以颜色值写入,ZWrite为On深度值写入,所以交汇部分白色。
//Off//OffOffOff在这里插入图片描述头像ZTest通过,颜色值写入缓存,ZWrite为On,深度值写入;白色ZTest通过所以颜色值写入,ZWrite为Off深度值不写入,所以交汇部分白色。

其他类推,就不一一列举了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值