[UnityShader笔记] 深度写入ZWrite&深度测试ZTest

[UnityShader笔记] 深度写入ZWrite&深度测试ZTest

创建两个Cube,一个蓝色距离相机近点;一个红色距离相机远点。如图所示
在这里插入图片描述
红Shader和蓝Shader使用相同的代码,但是Shader的名字要不一样,方便后面进行对比测试。

红蓝色Shader代码如下:

Shader "My/SampleShader2"
{
	Properties
	{
		_Color("Color", Color) = (1,1,1,1)
	}
	SubShader
	{
		Tags { "Queue"="Transparent" }
		LOD 100
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };
            fixed4 _Color; 
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                return fixed4(_Color.r,_Color.g,_Color.b,_Color.a);
            }
            ENDCG
        }
	}
}

我们新建2个Shader和2个材质球如下
在这里插入图片描述

为了便于后面对比,红蓝色的Shader的alpha参数设置为0.6。

在这里插入图片描述

修改之后结果如下:

在这里插入图片描述
并没有显示Alpha的变化,这个时候我们需要在Shader里面增加如下一行代码

blend SrcAlpha OneMinusSrcAlpha

放在Pass里面
在这里插入图片描述

这行指令意思就是将该Shader 计算出的颜色值(源颜色值,即红或者蓝色) * 源Alpha值(0.6) + 目标颜色值(可以理解为背景色) * (1-0.6),从而让蓝色方块展示出了40%的透明度。

结果如下

在这里插入图片描述
注意:这里我们使用了渲染队列”Transparent“

Tags { "Queue"="Transparent" }

渲染队列的值越小越先渲染,也就是说远处的先渲染,近处的后渲染,那么就不会出现远处的物体遮挡了近处的物体。由于红色Cube在蓝色Cube的后面,所以可以通过蓝色Cube看到红色Cube

那么如果我们想让红色的Cube出现在蓝色的Cube上面呢?也就是让远处的物体遮挡住近处的物体要怎么办呢,直接改“Queue”试试。我们把红色Cube的值由3000改为30004,观察如下:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

我们发现红色和蓝色交界处没有显示出红色,也就是说明直接修改这个Queue没有作用。

原因在于

ZTest  LEqual
ZWrite On

这两行代码在Shader中是默认存在的。

​ ZTest 可取值为:Greater , GEqual , Less , LEqual , Equal , NotEqual , Always , Never , Off,默认是 LEqual,ZTest Off 等同于 ZTest Always。

​ ZWrite 可取值为:On , Off,默认是 On。

系统中存在一个深度缓冲区。距离相机越近该值越小,越远该值越大。现在系统中有一个深度缓冲区,里面放入了蓝色的深度值比如是0.4和红色的深度值比如是0.5(因为红色离得远所以深度值会比蓝色的大)。

由于我们上面设置了蓝色的Queue是3000,红色的Queue是3004,那么蓝色就会先渲染,红色后渲染。系统就会默认先把蓝色的深度值放入深度缓冲区中。

由于蓝色的ZTest是小于等于自己的深度值的才能通过ZTest测试。但是这个时候红色0.5>0.4,并没有通过测试,所以我们就看不到红色。

关闭了深度测试或者深度写入之后,物体颜色的遮挡关系就会和渲染队列一致,即排在后面的会挡住前面的。那么我们要想让红色Cube挡住蓝色Cube就要修改ZTest的LEqual比较,或者将ZWrite给关闭。我们先关闭ZWrite进行测试。单独将蓝色Cube的深度写入ZWrite关闭

Tags { "Queue"="Transparent" }
ZWrite off

结果如下:

在这里插入图片描述

我们发现红色Cube挡住了蓝色Cube,实现了我们的需求。这个时候我们再试试另一种方法,ZTest是深度比较,我们不修改红色Cube,只修改蓝色的ZTest。改为ZTest Greater

Tags { "Queue"="Transparent" }
ZTest Greater

结果如下:

在这里插入图片描述

我们发现屏幕中没有了蓝色Cube,只有红色Cube和背景。

我们再进行另一个测试,只修改红色的Cube的ZTest。改为ZTest Greater

结果如下:

在这里插入图片描述
我们发现红色Cube被裁切掉了。

那么问题来了,红色的Cube哪里去了?答案是被背景挡住了。在上面只修改蓝色Cube的ZTest的时候发现蓝色没了,这两个原因是相同的,都是被背景挡住了。因为按照距离相机远近设置深度值的。那么背景的深度值假设为1,那么哪个Shader中使用了ZTest Greater,就会被后面的背景挡住。背景深度值大于蓝色深度值,也大于红色深度值。所以就是出现上面的两个现象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值