走进 Stencil Buffer 系列 0 : 模板缓冲和模板测试是什么?

作者:阿创
2020-04-27
5 2 1

编辑注:Stencil Buffer 相关文章站内其实有文章和日志涉及到过。比如较为大家关注的《笼中窥梦(Moncage)采访时就有提到(笼中窥梦@indienova)。这一次作者阿创投稿的系列文章将带大家了解更多相关的知识。

模板测试(Stencil Test)是现代渲染流水线的一环,其中涉及到的就是模板缓冲(Stencil Buffer),模板缓冲可以用来制作物体的遮罩、轮廓描边、阴影、遮挡显示等等效果,本章将带你了解什么是模板缓冲和模板测试。

一、模板缓冲是什么?

对现代渲染流水线有过了解的同学,一定知道深度测试(Depth Test)吧,深度测试可以从一个特定角度达到最近物体的排序的效果,与之相关的深度缓冲(Depth Buffer)里的值始终保存离摄像机最近物体的深度值(透明物体除外),这样就可以从前往后绘制物体了,避免了很多的 overdraw,大大提高了渲染性能,是渲染流水线不可或缺的一环。

但在深度测试之前还有一个测试,就是模板测试(Stencil Test),其知名度远远不及深度测试,有很多同学都只是偶尔听过一两下,不知道是什么东西,有啥用(就是之前的我了……)


下面就由我来带大家了解一下吧~

要想了解什么是模板测试,首先需要了解什么是模板缓冲(Stencil Buffer)。

其实和深度缓冲类似。模板缓冲也可以为屏幕上的每一个像素进行保存一个 8 位的无符号整数,即范围 0~255 的整数;

在 Unity 中,我们可以将这些模板值设置为我们想要的值,然后在随后渲染结果 Pass 与其进行比对,根据比对结果,我们就可以选择丢弃或是保留这个像素。此过程发生在渲染流水线的合并阶段中,具体在片元着色器之后,深度测试之前,被称为模板测试(Stencil Test)

通俗的来说,模板测试就像上图我们用的喷漆涂鸦一样。 我们首先准备一张中间镂空形状为 T 的纸板,还有一张空白底板。 当我们拿喷漆喷在镂空纸板上,结果只有镂空的部分喷漆才能通过。这样就在空白底板印上了 T 字图案。

以上喷漆其实就对应了我们每一个像素的颜色,而镂空纸板对应就是模板(测试),最后空白底板就对应了最终显示在我们眼前的屏幕。

我猜这就是 Stencil Buffer 名字的由来吧……

二、Unity 中的语法

1. Stencil 常见语法格式

Stencil{
    Ref referenceValue          // 参考值 默认值为 0
    Comp comparisonFunction     // 定义参考值与缓冲值比较的方法 默认值为 Always
    Pass stencilOperation       // 定义当通过模板测试时,根据参考值对缓冲值的处理方法 默认值为 keep
    Fail stencilOperation       // 定义当没有通过模板测试时,根据参考值对缓冲值的处理方法 默认为 keep
    ZFail stencilOperation      // 定义当通过模板测试却没有通过深度测试时,根据参考值对缓冲值的处理方法 默认为 keep
}

举个实际例子

Stencil{    
    Ref 1
    Comp Equal
    Pass Keep
}

上述代码的意思是: 我们自己设定了 Ref 参考值为 1。渲染 Pass 得到像素颜色后,拿参考值 1 与模板缓冲中此像素位置的缓冲值比对,只有 Equal 相等才算通过,并且 Keep 保持原有缓冲值,否则丢弃此像素颜色。

例子:指定只渲染 stencil 值为 1 的像素颜色

三、后续安排

通过本章,相信大家已经了解了什么是模板缓冲了。也简单了介绍其在 Unity ShaderLab 中的语法。

后续几章将介绍在实际开发中,运用模板缓冲达到效果实现(应该不会咕咕咕吧,作业不多的话……)

我也可能没讲清楚哈哈哈,大家有啥不懂也积极评论交流嘛,大家一起学习进步~

参考资料

下一章预告

运用 Stencil Buffer 实现的轮廓描边:

本文为用户投稿,不代表 indienova 观点。

近期点赞的会员

 分享这篇文章

阿创 

一句话介绍测试 

您可能还会对这些文章感兴趣

参与此文章的讨论

  1. 喵喵桑 2020-04-27

    起点有点高

您需要登录或者注册后才能发表评论

登录/注册