ShaderLab 语法:Alpha 测试 (Alpha testing)

Alpha 测试是拒绝将像素写入屏幕的最后机会。

当最终的输出颜色被计算出来后,可视情况将颜色的 alpha 值和一个固定值作比较。若未通过测试,则像素将不会被写至显示器。

语法

AlphaTest Off
渲染所有像素(默认)。
AlphaTest comparison AlphaValue
将 alpha 测试设置为仅渲染 alpha 值在一定范围内的像素。

比较 (Comparison)

比较 (Comparison) 可以选择以下词语:

大于 (Greater)仅渲染 alpha 值大于 AlphaValue 的像素。
大于等于 (GEqual)仅渲染 alpha 值大于或等于 AlphaValue 的像素。
小于 (Less)仅渲染 alpha 值小于 AlphaValue 的像素。
小于等于 (LEqual)仅渲染 alpha 值小于或等于 AlphaValue 的像素。
等于 (Equal)仅渲染 alpha 值等于 AlphaValue 的像素。
不等于 (NotEqual)仅渲染 alpha 值不等于 AlphaValue 的像素。
总是 (Always)渲染所有像素。这在功能上相当于 Alpha 测试关 (AlphaTest Off)
永不 (Never)不渲染任何像素。

AlphaValue

在 0 和 1 之间的浮点数。它也可能是浮动或范围属性的引用变量,这种情况下应该写在标准的方括号内([变量名])。

详细信息

在渲染有透明部分的凹对象时,alpha 测试很重要。显卡保存着写入屏幕的每个像素的深度记录。若新像素远于已渲染的像素,则这个新像素将不被写入显示。这意味着即使使用混合,对象也不会显示出来。

在此图中,左边的树是用 AlphaTest 渲染的。注意图中的像素完全透明或完全不透明的情况。中间的树仅使用 Alpha 混合 (Alpha Blending) 来渲染 - 注意附近树枝的透明部分是如何利用深度缓存覆盖远处树叶的。右边的树由最后一个示例着色器渲染 - 该着色器通过执行混合与 alpha 测试来隐藏假象。

示例

最简单的可能示例:赋予其带有 alpha 通道的纹理。对象只在 alpha 值大于 0.5 处显示

Shader "Simple Alpha Test" {
	Properties {
		_MainTex ("Base (RGB) Transparency (A)", 2D) = "" {}
	}
	SubShader {
		Pass {
			// 只渲染 alpha 大于 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 {
			// 使用以上定义的分解 (Cutoff) 参数确定
			// 要渲染的内容。
			AlphaTest Greater [_Cutoff]
			Material {
				Diffuse (1,1,1,1)
				Ambient (1,1,1,1)
			}
			Lighting On
			SetTexture [_MainTex] { combine texture * primary }
		}
	}
} 

渲染植物和树木时,许多游戏都有 alpha 测试特有的硬边缘。解决这个问题的方法是对对象进行两次渲染。这第一个通道中,我们使用 alpha 测试只渲染不透明度大于 50% 的像素。在第二个通道中,我们对切除部分的图形进行 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 {
		// 设置基础光照
		Material {
			Diffuse [_Color]
			Ambient [_Color]
		}
		Lighting On

		// 渲染正面和背面多边形。
		Cull Off

		// 第一通道:
		//   渲染不透明度大于 [_Cutoff] 的像素
		Pass {
			AlphaTest Greater [_Cutoff]
			SetTexture [_MainTex] {
				combine texture * primary, texture
			}
		}

		// 第二通道:
		//   渲染半透明细节。
		Pass {
			// 不写入深度缓存
			ZWrite off
			// 不写入已经写入的像素。
			ZTest Less
			// 只渲染小于或等于该值的像素
			AlphaTest LEqual [_Cutoff]

			// 设置 alpha 混合
			Blend SrcAlpha OneMinusSrcAlpha

			SetTexture [_MainTex] {
				combine texture * primary, texture
			}
		}
	}
} 

请注意:我们在子着色器 (SubShader) 中而不是各个通道中做了一些设置。子着色器 (SubShader) 中设置的任何状态都会被它内部的通道作为默认值继承。

Page last updated: 2013-06-28