unity-shader-模板测试

unity-shader-模板测试


前篇


Unity渲染流水线中简单提到,在光栅化阶段的逐片元操作步骤中,会有一个模板测试(Stencil),这次来深入了解一下。

Unity官方文档定义如下:
模板缓冲区可用作一般目的的每像素遮罩,以便保存或丢弃像素。 模板缓冲区通常是每像素 8 位整数。该值可以写入、递增或递减。后续绘制调用可以根据该值进行测试,以确定在运行像素着色器之前是否应丢弃像素。
Unity Shader入门精要》大致解释如下:
如果开启了模板测试,GPU会首先读取模板缓冲区中该片元位置的模板值,然后将该值和读取到的参考值进行比较,若没有通过测试,则该片元则会被舍弃。但是不管片元有没有通过测试,我们都可以根据模板测试结果来修改模板缓冲区。其中的比较函数和缓冲区操作都是可以由开发者指定的。

官方文档语法释义(比较函数和模板操作不再罗列):

  • Ref 要比较的参考值(如果 Comp 是always以外的任何值)和/或要写入缓冲区的值(如果 Pass、Fail 或 ZFail 设置为替换)。值为 0 到 255 之间的整数。
  • ReadMask 一个 8 位掩码,值为 0 到 255 之间的整数,用于比较参考值和缓冲区的内容 (referenceValue&readMask)comparisonFunction(stencilBufferValue&readMask)。默认值:_255_。
  • WriteMask 这是一个 8 位掩码,值为 0 到 255 之间整数,写入缓冲区时使用。请注意,与其他写掩码一样,它指定写操作将影响模板缓冲区的哪些位(例如 WriteMask 0 表示不会影响任何位,也不会写入 0)。默认值:_255_。
  • Comp 用于将参考值与缓冲区的当前内容进行比较的函数。默认值:_always_。
  • Pass 如果模板测试(和深度测试)通过,如何处理缓冲区的内容。默认值:_keep_。
  • Fail 如果模板测试(和深度测试)失败,如何处理缓冲区的内容。默认值:_keep_。
  • ZFail 如果模板测试通过但深度测试失败,如何处理缓冲区的内容。默认值:_keep_。

可用枚举值

  • Comp comparisonFunction,比较函数

    1
    2
    0:Disable 1:Never 2:Less 3:Equal 4:LessEqual 5:Greater 6:NotEqual 7:GreaterEqual 8:Always
    [Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp ("StencilComp", Int) = 8
  • Pass/ZFail//Fail/stencilOp,为每一种结果指定一个操作

    1
    2
    0:Keep 1:Zero 2:Replace 3:IncrSat 4:DecrSat 5:Invert 6:IncrWrap 7:DecrWrap
    [Enum(UnityEngine.Rendering.StencilOp)] _StencilOp ("StencilOp", int) = 2