模板缓存区与颜色缓存区和深度缓存区类似,模板缓存区可以为屏幕上的每个像素点保存一个无符号整数值(通常的话是个8位整数)。这个值的具体意义视程序的具体应用而定。在渲染的过程中,可以用这个值与一个预先设定的参考值相比较,根据比较的结果来决定是否更新相应的像素点的颜色值。这个比较的过程被称为模板测试。
如果模板测试通过,则相应的像素点更新,否则不更新。
模板测试发生在透明度测试(alpha test)之后,深度测试(depth test)之前。
模板测试流程图1.0Stencil Test语法
Stencil Test的指令可以写在SubShader中,也可以写在Pass中,它们包含在Stencil{}代码块中。
Stencil Test完整语法结构如下:
Stencil{
Ref referenceValue
ReadMask readMask
WriteMask writeMask
Comp comparisonFunction
Pass stencilOperation
Fail stencilOperation
ZFail stencilOperation
}
-
Ref referenceValue:用来设定参考值referenceValue,这个值将用来与模板缓存中的值进行比较。
referenceValue是一个取值范围位0-255的整数。 -
ReadMask readMask:readMask将和referenceValue以及stencilBufferValue分别进行按位与【&】操作。
readMask取值范围是0-255的整数,默认值是255,二进制位11111111,即读取的时候不对referenceValue和stencilBufferValue产生效果。 -
WriteMask writeMask:writeMask是当写入模板缓存时进行掩码操作(按位与【&】)。
writeMask取值范围是0-255的整数,默认值是255,即当修改stencilBufferValue值时,写入的仍然是原始值。 - Comp comparisonFunction:定义参考值(referenceValue)与模板缓存值(stencilBufferValue)比较的操作函数,默认值:always 。
- Pass stencilOperation:定义当模板测试和深度测试通过时,则根据stencilOperation对模板缓存值(stencilBufferValue)进行处理,默认值:keep。
- Fail stencilOperation:定义当模板测试失败时,则根据stencilOperation对模板缓存值(stencilBufferValue)进行处理,默认值:keep。
- ZFail stencilOperation:定义当模板测试通过而深度测试失败时,则根据stencilOperation值对模板缓存值(stencilBufferValue)进行处理,默认值:keep。
Comp,Pass,Fail 和ZFail将会应用给背面消隐的几何体(只渲染前面的几何体),除非Cull Front被指定,在这种情况下就是正面消隐的几何体(只渲染背面的几何体)。
可以精确的指定双面的模板状态通过定义CompFront,PassFront,FailFront,ZFailFront(当模型为front-facing geometry使用)和ComBack,PassBack,FailBack,ZFailBack(当模型为back-facing geometry使用)
2.0 Stencil Test判断依据
和深度测试一样,在Unity中,每个像素的模板测试也有它自己的计算公式,如下:
if(referenceValue & readMask comparisonFunction stencilBufferValue&readMask)
//通过测试,保留像素
else
//未通过测试,抛弃像素
referenceValue是由Ref来定义的,这个是由程序来定义,readMask是模板值的读取掩码,它和referenceValue进行按位与操作作为公式左边的结果。
stencilBufferValue是对应当前模板缓存区的值,同样与readMask做按位掩码与操作,结果做为右边的部分。
comparisonFunction比较操作通过Comp命令定义,公式左右两边的结果将通过它进行判断,其取值及其意义如下面列表所示。
比较方法 | 说明 |
---|---|
Greater | 相当于“>”操作,即仅当左边>右边,模板测试通过,渲染像素 |
GEqual | 相当于“>=”操作,即仅当左边>=右边,模板测试通过,渲染像素 |
Less | 当相于“<”操作,即仅当左边<右边,模板测试通过,渲染像素 |
LEqual | 当于“<=”操作,即仅当左边<=右边,模板测试通过,渲染像素 |
Equal | 相当于“=”操作,即仅当左边=右边,模板测试通过,渲染像素 |
NotEqual | 相当于“!=”操作,即仅当左边!=右边,模板测试通过,渲染像素 |
Always | 不管公式两边为何值,模板测试总是通过,渲染像素 |
Never | 不敢公式两边为何值,模板测试总是失败 ,像素被抛弃 |
3.0 模板缓存值的更新
不管是否通过测试,都可以对缓存中的模板值进行操作。具体到怎么更新,则由程序员自己定义。
上面关于模板缓存语法中,Pass,Fail,ZFail等命令就是根据不同判断条件对模板缓存区的值(stencilBufferValue)进行更新的操作,这些命令取值(stencilOperation)的含义如下面列表所示:
操作 | 说明 |
---|---|
Keep | 保留当前缓存中的内容,即stencilBufferValue不变 |
Zero | 将0写入缓存,即stencilBufferValue值变为0 |
Replace | 将参考值写入缓存,即将referenceValue赋值给stencilBufferValue |
IncrSat | stencilBufferValue加1,如果stencilBufferValue超过255了,那么保留为255,即不大于255 |
DecrSat | stencilBufferValue减1,如果stencilBufferValue超过为0,那么保留为0,即不小于0 |
Invert | 将当前模板缓存值(stencilBufferValue)按位取反 |
IncrWrap | 当前缓存的值加1,如果缓存值超过255了,那么变成0,(然后继续自增) |
DecrWrap | 当前缓存的值减1,如果缓存值已经为0,那么变成255,(然后继续自减) |
在更新模板缓存值的时候,也有writeMask进行掩码操作,用来对特定的位进行写入和屏蔽,默认值为255(11111111),即所有位数全部写入,不进行屏蔽操作。
Unity在G-buffer Pass和照明Pass中会将模板测试用于其他目的,并且Unity定义的模板状态会被忽略,因此模板测试会在延迟渲染路径中收到限制。因此,在延迟渲染路径中使用模板测试无法将物体屏蔽。
即便如此,依然可以在物体被渲染之后修改缓存中的模板值,而那些使用前向渲染路径的物体,会在延迟渲染路径之后在设再设置它们的模板状态,然后执行模板测试。
网友评论