AlphaTest 透明度测试
1.顶点片源着色器实现介绍:
**透明度测试核心原理:
对于Alpha透明通道小于阈值的片元直接舍弃掉,被舍弃掉的这些片元不会对颜色缓冲产生影响,也不会在进行任何处理
下面是两种舍弃阀值外的片元方式:
//裁掉Alpha小于0的片元
clip(texColor.a-_Cutoff);
//裁掉Alpha小于0的片元
if(texColor.a-_Cutoff<0)
{
discard;
}
透明度测试缺点:
透明度测试得到的效果,要么完全透明,要么不透明,不能像透明度混合那样,进行渐渐透明。且得到的透明度效果在边缘处往往参差不齐,有锯齿,这是因为在边界处纹理的透明度的变化精度问题。
Tags
使用了透明度测试的 Shader 都应该在SubShader 中设置这三个标签
Tags { "Queue"="AlphaTest" "RenderType"="TransparentCutout" "IgnoreProjector"="True"}
说明:
"Queue"="AlphaTest"
开启透明度测试
"RenderType"="Transparent"
指明该shader是一个使用了透明度的Shader。
"IgnoreProjector"="True"
这个shader忽略投影器(Projectors)的影响。
注意事项:
1.Fallback "Transparent/Cutout/VertexLit"
是不能少的,因为我们在处理阴影时他能起到很大的作用。
2.若要该物体附带阴影,需要声明属性 _Cutoff
因为Fallback的 VertexLit Shader在计算透明度测试时使用了**_Cutoff**属性,因此我们的属性中必须要包含 _Cutoff
这个属性,否则会导致无法正常使用阴影功能。
3.若需阴影跟随物体透明化,如下图, 需在属性中声明 _Color
属性,同理Fallback的 VertexLit Shader在计算阴影时使用到了这个属性,否则会导致阴影无法跟随物体透明化。
下图的透明度测试效果图 展示了 通过舍弃alpha通道小于0的片元,实现物体透明效果,以及透明通道的阴影的裁切效果。
下面附上源shader:
Shader "Unlit/Unity_AlphaTest"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Cutoff("Alpha Cutoff",Range(0,1))=0.5
_Color("Diffuse",Color) =(1,1,1,1)
}
SubShader
{
Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="Transparent"}
LOD 100
Pass
{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
fixed _Cutoff;
//由于"Transparent/Cutout/VertexLit" 在计算透明阴影时使用了_Color属性 因此我们的Shader中必须包含为_Color的属性 否则阴影无法进行透明化
fixed4 _Color;
struct v2f
{
float4 vertex:SV_POSITION;
float2 uv:TEXCOORD0;
float3 worldNomal:TEXCOORD1;
float3 worldPos:TEXCOORD2;
SHADOW_COORDS(3)
};
v2f vert (appdata_base v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
o.worldNomal=UnityObjectToWorldNormal(v.normal);
o.worldPos=mul(unity_ObjectToWorld,v.vertex);
//计算阴影纹理坐标
TRANSFER_SHADOW(o);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
float3 worldNomalDir=normalize(i.worldNomal);
float3 worldLightDir=normalize(UnityWorldSpaceLightDir(i.worldPos));
//主贴入图采样
float4 texColor=tex2D(_MainTex,i.uv);
float3 albedo=texColor.rgb*_Color.rgb;
//裁掉透明像素
//clip(texColor.a-_Cutoff);
if(texColor.a-_Cutoff<0)
{
discard;
}
//提升主UV的反照率 相当于提升清晰度
fixed3 amnient= UNITY_LIGHTMODEL_AMBIENT.xyz*albedo;
//计算光照衰减
UNITY_LIGHT_ATTENUATION(atten, i,i.worldPos);
//计算漫反射
float3 diffuse=_LightColor0.rgb*albedo*(dot(worldNomalDir,worldLightDir)*0.5+0.5);
float3 color=diffuse+amnient*atten;
return fixed4(color,1.0);
}
ENDCG
}
}
Fallback "Transparent/Cutout/VertexLit"
}
2.surfaceShader实现介绍:
相比之下使用surface Shader实现更为简单快速,我们基本不用写shader代码,因为我们所需要的功能surfaceShader 都已经给我们提供好了,我们只需要配置下指示命令即可。
配置如下:
// alphatest:_CutOff 根据变量名字来控制透明度混合和透明度测试
//addShadow 给当前透明通道物体使用阴影
//noshadow 关闭自身接收阴影 根据选择开关
#pragma surface surf Standard alphatest:_CutOff addshadow noshadow
开启效果如下图:
未开启深度测试:
源码如下:
Shader "Custom/AlphaTest"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_CutOff("CutOut",Range(0,1))=0
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader
{
Tags { "RenderType"="Transparent" "Queue"="AlphaTest" }
LOD 200
Cull Off
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
// alphatest:_CutOff 根据变量名字来控制透明度混合和透明度测试
//addShadow 给当前透明通道物体使用阴影
//noshadow 关闭自身接收阴影 根据选择开关
#pragma surface surf Standard alphatest:_CutOff addshadow noshadow
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_BUFFER_END(Props)
void surf (Input IN, inout SurfaceOutputStandard o)
{
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
努力积才能,壹叶便成名!