美文网首页
Shader笔记——Stencil Test

Shader笔记——Stencil Test

作者: 莫忘初心_倒霉熊 | 来源:发表于2021-10-24 21:06 被阅读0次

    模板缓存区与颜色缓存区和深度缓存区类似,模板缓存区可以为屏幕上的每个像素点保存一个无符号整数值(通常的话是个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  
      }  
    
    1. Ref referenceValue:用来设定参考值referenceValue,这个值将用来与模板缓存中的值进行比较。
      referenceValue是一个取值范围位0-255的整数。
    2. ReadMask readMask:readMask将和referenceValue以及stencilBufferValue分别进行按位与【&】操作。
      readMask取值范围是0-255的整数,默认值是255,二进制位11111111,即读取的时候不对referenceValue和stencilBufferValue产生效果。
    3. WriteMask writeMask:writeMask是当写入模板缓存时进行掩码操作(按位与【&】)。
      writeMask取值范围是0-255的整数,默认值是255,即当修改stencilBufferValue值时,写入的仍然是原始值。
    4. Comp comparisonFunction:定义参考值(referenceValue)与模板缓存值(stencilBufferValue)比较的操作函数,默认值:always 。
    5. Pass stencilOperation:定义当模板测试和深度测试通过时,则根据stencilOperation对模板缓存值(stencilBufferValue)进行处理,默认值:keep。
    6. Fail stencilOperation:定义当模板测试失败时,则根据stencilOperation对模板缓存值(stencilBufferValue)进行处理,默认值:keep。
    7. 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定义的模板状态会被忽略,因此模板测试会在延迟渲染路径中收到限制。因此,在延迟渲染路径中使用模板测试无法将物体屏蔽。
    即便如此,依然可以在物体被渲染之后修改缓存中的模板值,而那些使用前向渲染路径的物体,会在延迟渲染路径之后在设再设置它们的模板状态,然后执行模板测试。

    相关文章

      网友评论

          本文标题:Shader笔记——Stencil Test

          本文链接:https://www.haomeiwen.com/subject/oxldaltx.html