ShaderLab: Legacy Alpha Testing
原文链接:https://docs.unity3d.com/Manual/SL-AlphaTest.html
Alpha测试是阻止一个像素被写到屏幕上的最后一个机会。
请注意:当进行片段shader编程时,AlphaTest命令无效,在大多数平台上,alpha测试在shader中是使用HLSL的clip()函数完成的。现在,我们推荐使用可编程的shader来代替SetTexture命令。
在最后输出的颜色被计算出来后,可以选择性的把这个颜色的透明度与一个固定值相比较。如果测试失败,像素将不会写入到显示上。
语法
AlphaTest Off
渲染所有像素(默认),或者...
AlphaTest comparison AlphaValue
建立一个Alpha测试只渲染alpha值在某个确定区间内的像素。
比较
下面是比较语句:
Greater 只渲染Alpha值比AlphaValue值大的像素。
GEqual 只渲染Alpha值大于等于AlphaValue值的像素。
Less 只渲染Alpha值比AlphaValue值小的像素。
LEqual 只渲染Alpha值小于等于AlphaValue值的像素。
Equal 只渲染Alpha值等于AlphaValue值的像素。
NotEqual 只渲染Alpha值不等于AlphaValue值的像素。
Always 渲染所有像素,这个功能相当于关闭了Alpha测试。
Never 不渲染任何像素。
AlphaValue
一个0-1之间的浮点数字。它也可以是一个浮点变量或是一个范围属性,在这种情况下它必须使用方括号来表示([VariableName])。
细节
当渲染凹面的物体的透明部分的时候Alpha测试是重要的。显卡会持有每个要显示到屏幕上的像素的深度值记录。如果一个新的像素比已经渲染的像素更远,新的像素将不会写入到显示上。这意味着即使有融合,对象将不会显示。
(图片见原网页)
在这个图中,左边的树使用透明度测试来渲染。请注意它上面的像素要么是透明的要么是不透明的。中间的树只使用透明度融合来渲染,请注意由于深度buffer,树枝附近的透明部分是怎样覆盖远处的叶子的。右边的树使用下面的案例shader来渲染,此shader使用融合和alpha测试混合的方式来隐藏所有工件。
例子
最简单的可能性的例子,给其分配了一个纹理的alpha通道。只有纹理中Alpha值大于0.5才会被显示。
Shader "Simple Alpha Test" {
Properties {
_MainTex ("Base (RGB) Transparency (A)", 2D) = "" {}
}
SubShader {
Pass {
// Only render pixels with an alpha larger than 50%
AlphaTest Greater 0.5
SetTexture [_MainTex] { combine texture }
}
}
}
只靠它自己不是特别好。让我们添加一些光照并且使测试值可以调节。
Shader "Cutoff Alpha" {
Properties {
_MainTex ("Base (RGB) Transparency (A)", 2D) = "" {}
_Cutoff ("Alpha cutoff", Range (0,1)) = 0.5
}
SubShader {
Pass {
// Use the Cutoff parameter defined above to determine
// what to render.
AlphaTest Greater [_Cutoff]
Material {
Diffuse (1,1,1,1)
Ambient (1,1,1,1)
}
Lighting On
SetTexture [_MainTex] { combine texture * primary }
}
}
}
当渲染植物和树,很多游戏都有典型的Alpha测试硬边。一个解决方案是渲染对象两次。在第一个pass中,我们使用Alpha测试只去渲染透明度大于50%的不透明的像素。在第二个pass中,我们使用Alpha融合被截取掉的图像,不记录像素的深度值。由于更远的分支会覆盖更近的分支,我们会有一些混乱,但是事实上,这种情况很难看到因为叶子上面有很多视觉细节。
Shader "Vegetation" {
Properties {
_Color ("Main Color", Color) = (.5, .5, .5, .5)
_MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
_Cutoff ("Base Alpha cutoff", Range (0,.9)) = .5
}
SubShader {
// Set up basic lighting
Material {
Diffuse [_Color]
Ambient [_Color]
}
Lighting On
// Render both front and back facing polygons.
Cull Off
// first pass:
// render any pixels that are more than [_Cutoff] opaque
Pass {
AlphaTest Greater [_Cutoff]
SetTexture [_MainTex] {
combine texture * primary, texture
}
}
// Second pass:
// render in the semitransparent details.
Pass {
// Dont write to the depth buffer
ZWrite off
// Don't write pixels we have already written.
ZTest Less
// Only render pixels less or equal to the value
AlphaTest LEqual [_Cutoff]
// Set up alpha blending
Blend SrcAlpha OneMinusSrcAlpha
SetTexture [_MainTex] {
combine texture * primary, texture
}
}
}
}
请注意,我们在SubShader中有一些设置,而不是在每个独立的pass中。在SubShader中的设置将被其pass继承为默认设置。