1.模板测试Stencil
在per-fragment阶段,发生在透明测试之后、深度测试之前的操作
类似遮罩,对color buffer中的内容做一个判断,通过判断的将会被绘制在屏幕上(像素点更新),反之则被裁剪
Stencil buffer值为0-255(uint8)
Stencil
{
Ref referenceValue
ReadMask readMask
WriteMask writeMask
Comp comparisonFunction
Pass stencilOperation
Fail stencilOperation
ZFail stencilOperation
}
comparisonFunction
stencilOperation(是否更新StencilBufferValue)
Stencil效果分析:
三层:原场景、蒙版(一般自身不渲染)、蒙版后的物体
原场景略
蒙版:
核心:subshader下添加ColorMask,关闭深度写入,写stencil,将其渲染顺序后移
在正常场景的下一步绘制,always使在蒙版中的像素都能通过stencilTest,通过的像素StencilBufferValue全部更新为shader中指定的referenceValue
ColorMask0来使其不被渲染
蒙版后的物体:
核心:写stencil,渲染顺序比蒙版后
在蒙版绘制完后绘制,对于蒙版中的像素,StencilBufferValue已更新,此时只要将物体自己的referenceValue设置为可以通过comparison的值即可
2.深度测试 Ztest
Pre-fragment阶段,发生在模板设置之后,透明混合之前
Overlay:像素被重复绘制
将物体的深度值与Zbuffer中的深度值进行比较,通过则写入颜色缓冲区(更新颜色)
Zbuffer值为float(0-1),一般为24位
注意Zbuffer值不以线性而一般以倒数形式存储(近处精度大)
画家算法:先画远后画近(overdraw产生)
Zwrite:是否将当前深度写入Zbuffer
Ztest:是否通过深度缓冲并更新颜色
深度测试通过,深度写入开启:写入深度缓冲区,写入颜色缓冲区。
深度测试通过,深度写入关闭:不写深度缓冲区,写入颜色缓冲区。
深度测试失败,深度写入开启:不写深度缓冲区,不写颜色缓冲区。
深度测试失败,深度写入关闭:不写深度缓冲区,不写颜色缓冲区。
Ztest比较操作同stencil(都是用compare宏)
RenderQueue:绘制顺序,小的早绘制,大的晚绘制
Background:1000
Geometry(Default):2000
AlphaTest:2450
Transparent:3000
Overlay:4000
不透明物体从前往后绘制,透明物体从后往前绘制(overlay)
核心:subshader下声明ZWrite模式和ZTest比较模式
Early-z可在vertshader、光栅化之后,fragshader之前进行深度测试,剔除掉无需渲染的物体,减少overdraw,但之后仍要进行检查确保遮挡关系的正确
作业:
利用stencil实现卡通渲染飘眉效果,让眉毛不被头发遮挡
Stencil:
先渲染眉毛,为眉毛设置Reference值,通过则替换Reference值
再渲染头发,其Reference值大于脸部等其他位置,小于眉毛,这样在除眉毛以外的区域都会渲染,眉毛处不会渲染头发
再正常渲染其他物体
ZTest:
先正常渲染头发
再分两次渲染眉毛:第一次正常渲染未被遮挡的部分(ZTestLEqual),第二次渲染被遮挡的部分(ZTestGEqual)
再正常渲染其他物体
效果: