unity ShaderLab 基础之【透明测试AlphaTest】AlphaTest详解

一 基础介绍

1 透明度

当一个具有透明度的物体挡住另一个可见问题时,光线会穿过带有透明度的物体,使我们能看到后面那个物体的信息。一般情况吓alpha的值区间为(0-1),0为完全不可见,1为完全可见。

2 缓冲区

【颜色缓冲区】:也叫帧缓冲区,场景中的物体的像素都要写入该缓冲区,然后再渲染到屏幕上显示
【深度缓冲区】:用于记录颜色缓冲区中每个像素的深度值,通过深度缓冲区,我们可以通过深度测试来确定像素的遮挡关系
【模版缓冲区】:与深度缓冲类似,但这个值是可以自己设定的。,通过设置每个像素的模板缓冲值,就可以指定只渲染某些像素,用于实现类似遮罩之类的效果。

4 透明测试 AlphaTest

透明测试开启时,当前像素根据设定条件决定是否输出颜色

5 深度测试ZTest、透明测试AlphaTest、混合模式Blend的关系

总的来说深度测试ZTest决定遮挡关系,是否用当前像素替换缓存像素
透明测试alphatest决定是否显示透明度达标的像素,要么完全显示,要么完全不显示
颜色混合blend决定通过测试的像素如果重合如何显示

【当前像素】 当前像素就是指当前shader脚本所属的模型像素
【缓存限速】 准备输出到屏幕上的像素,被称为缓存像素
【透明测试】 实际上就是描述如何使用透明度确定缓存像素的替换规则
【启用深度测试的必要条件】AlphaTest不为Off

二 实例

【准备工作】
首先创建一个方块A,创建材质与shader并将他们赋给方块。将下面代码放入shader中,并选择一个带有透明度的图片作为贴图。设置_alphaValue值为1
在这里插入图片描述

透明测试有两种实现方式,分别是片元着色器和表面着色器
1.片元着色器中实现透明测试的代码
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/B"
{
	Properties
	{
        _MainTex ("贴图", 2D) = "white" {}
		_BackgroundColor ("背景颜色", Color) = (1, 1, 1, 1)
        _alphaValue("alpha", range(0.00,1.00)) = 0.5
	}
	SubShader
	{
		Pass
		{
            //设置透明队列
            Tags {"Queue" = "Transparent" "RenderType"="Transparent" }
            //关闭裁剪,这样透过镂空的地方就能看到后面了
            Cull Off
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
            //从程序传染顶点渲染器的数据
			struct a2v
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};
            //从顶点渲染器传入片元渲染器的数据
			struct v2f
			{			
				float4 position : SV_POSITION;
				float2 uv : TEXCOORD0;
			};
 
			//格子背景
            sampler2D _MainTex;
			fixed4 _BackgroundColor;
            fixed _alphaValue;
            //顶点着色器
			v2f vert (a2v v)
			{
				v2f o;
                //将像素空间从模型转为裁剪空间
				o.position = UnityObjectToClipPos(v.vertex);
				o.uv = v.uv;
				return o;
			}
			//片段着色器
			fixed4 frag (v2f o) : COLOR
			{
                //组装贴图和uv与背景颜色合成像素
				fixed4 renderTex = tex2D(_MainTex, o.uv) * _BackgroundColor;
                //clip 函数等同于
                //if((renderTex.a - _alphaValue)<0.0){
                //	discard;
                //}
                //透明测试 核心函数,满足透明度条件才显示
                clip(renderTex.a - _alphaValue);
                //合成贴图、遮罩、线的像素
                return renderTex;
			}
			ENDCG
		}
	}
}

2.表面着色器中实现透明测试的代码

表面着色器需要时用单独的命令
深度测试指令:

//启用透明测试,如果当前像素透明度大于 _alphaValue 值,就显示该像素,否则就放弃
alphatest greater [_alphaValue]

命令:

指令 说明 实例
Greater 当前像素透明度 > 指定数值,就显示当前像素。否则就放弃 alphatest greater [_alphaValue] //类似于抠图
Less 小于 类似于反向抠图
GEqual 大于等于
LEqual 小于等于
Equal 等于
NotEqual 不等于
Always 总是
Never 永不
Off 关闭

【shader代码】

Shader "Custom/B"
{
	Properties
	{
        _MainTex ("贴图", 2D) = "white" {}
		_BackgroundColor ("背景颜色", Color) = (1, 1, 1, 1)
        _alphaValue("alpha", range(0.00,1.00)) = 0.5
	}
    SubShader
    {
        Tags {"Queue" = "Transparent" "RenderType"="Transparent" }
        //关闭裁剪这样就嫩看到镂空的背面
        Cull Off 
        //关闭深度写入
        ZWrite Off 

        //透明测试  开启透明测试,当前限速透明度 > _alphaValue 时,显示当前限速
        AlphaTest Greater [_alphaValue]
        Pass
        {
            //输出颜色
            SetTexture[_MainTex]
        }
    }  
}
保存shader后,在Inspactor面板中添加一张带有透明度的贴图,并设置AlphaTestValue值为1,就会得到下面的镂空效果

在这里插入图片描述

发布了134 篇原创文章 · 获赞 37 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/lengyoumo/article/details/104226067