• Shader 模板缓冲和模板测试


    http://blog.sina.com.cn/s/blog_6e159df70102xa67.html
    模板缓冲的概念
    Unity官方的Shader文档根本没有提到这个玩意,这个概念也是看到了UGUI build-in shader 的Mask实现才发现了这个部分。 先说一下基础知识,在图形学中一个像素会有如下缓存:
    • 颜色缓存color buffer/pixel buffer:储存该点即将显示的颜色,RGBA值
    • 深度缓存depth buffer/z buffer:储存该点的深度,z
    • 模板缓存stencil buffer:通常用作限制渲染区域。 更高级用法需结合深度缓冲,例如某像素的模板缓冲值会随着其是否通过深度缓冲测试而改变。
    • 累积缓存Accumulation Buffer: 与颜色缓冲类似,同样储存一个RGBA值。累积缓存是为合成多幅图像而设计的,累积缓存提供了一种在保持好的颜色分辨率下实现在场景中“多重曝光(multiple exposures)”的方法。使用累积缓存可以产生许多图像效果来提高图像的真实性,其中包括:反走样、运动模糊、软阴影、深度域(景深)和卷积。要产生这些效果,必须将图像渲染多次,对场景位置(或所选的物体)进行微小的、渐增的改变,然后累积结果。
    stencil与颜色缓冲区和深度缓冲区类似,模板缓冲区可以为屏幕上的每个像素点保存一个无符号整数值(通常的话是个8位整数)。这个值的具体意义视程序的具体应用而定。在渲染的过程中,可以用这个值与一个预先设定的参考值相比较,根据比较的结果来决定是否更新相应的像素点的颜色值。这个比较的过程被称为模板测试Stencil Test。模板测试发生在透明度测试(alpha test)之后,深度测试(depth test)之前。如果模板测试通过,则相应的像素点更新,否则不更新。图形渲染管线中,基于单个像素的测试操作的顺序如下图

    相关语法


    上图是UGUI中Image的默认Shader,最后一张是通用的stencil格式
    • Ref用来设定参考值referenceValue,这个值将用来与模板缓冲中的值进行比较。referenceValue是一个取值范围位0-255的整数。
    • ReadMask 从字面意思的理解就是读遮罩,readMask将和referenceValue以及stencilBufferValue进行按位与(&)操作,readMask取值范围也是0-255的整数,默认值为255,二进制位11111111,即读取的时候不对referenceValue和stencilBufferValue产生效果,读取的还是原始值。
    • WriteMask是当写入模板缓冲时进行掩码操作(按位与&),writeMask取值范围是0-255的整数,默认值也是255,即当修改stencilBufferValue值时,写入的仍然是原始值。
    • Comp是定义参考值(referenceValue)与缓冲值(stencilBufferValue)比较的操作函数,默认值:always 
    • Pass是定义当模板测试(和深度测试)通过时,则根据(stencilOperation值)对模板缓冲值(stencilBufferValue)进行处理,默认值:keep
    • Fail是定义当模板测试(和深度测试)失败时,则根据(stencilOperation值)对模板缓冲值(stencilBufferValue)进行处理,默认值:keep
    • ZFail是定义当模板测试通过而深度测试失败时,则根据(stencilOperation值)对模板缓冲值(stencilBufferValue)进行处理,默认值:keep
    Comp,Pass,Fail 和ZFail将会应用给Cull Back(只渲染前面的几何体),除非Cull Front被指定,在这种情况下就是Cull Front(只渲染背面的几何体)。你也可以精确的指定双面的模板状态通过定义CompFront,PassFront,FailFront,ZFailFront(当模型为front-facing geometry(Cull Back)使用)和ComBack,PassBack,FailBack,ZFailBack(当模型为back-facing geometry(Cull Font)使用)
    测试的判断依据
    和深度测试一样,在unity中,每个像素的模板测试也有它自己一套独立的依据,具体公式如下:

    if(referenceValue&readMask comparisonFunction stencilBufferValue&readMask

    通过像素

    else

    抛弃像素

    在这个公式中,主要分comparisonFunction的左边部分和右边部分

    referenceValue是有Ref来定义的,这个是由程序员来定义的,readMask是模板值读取掩码,它和referenceValue进行按位与(&)操作作为公式左边的结果,默认值为255,即按位与(&)的结果就是referenceValue本身。

    stencilBufferValue是对应位置当前模板缓冲区的值,同样与readMask做按位掩码与操作,结果做为右边的部分。

    comparisonFunction比较操作通过Comp命令定义,公式左右两边的结果将通过它进行判断,其取值及其意义如下面列表所示。



    Greater
    相当于“>”操作,即仅当左边>右边,模板测试通过,渲染像素
    GEqual
    相当于“>=”操作,即仅左边>=右边,模板测试通过,渲染像素
    Less
    相当于“<”操作,即仅当左边<右边,模板测试通过,渲染像素
    LEqual
    相当于“<=”操作,即仅当左边<=右边,模板测试通过,渲染像素
    Equal
    相当于“=”操作,即仅当左边=右边,模板测试通过,渲染像素
    NotEqual
    相当于“!=”操作,即仅当左边!=右边,模板测试通过,渲染像素
    Always 不管公式两边为何值,模板测试总是通过,渲染像素
    Never 不敢公式两边为何值,模板测试总是失败 ,像素被抛弃
    更新缓冲值

    在上一步的模板测试之后,无论模板测试通过与否,都要对模板进行相应的更新。具体到怎么更新,则由程序员自己定义。上面关于模板缓冲语法中,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,(然后继续自减)  。
  • 相关阅读:
    [杭电_HDU] 2013
    动态调整线程数的python爬虫代码分享
    wampserver 配置的几个坑(雾
    wampserver apache 403无权限访问 You don't have permission to access /index.html on this server
    [爬坑日记] 安卓模拟器1903蓝屏 没开hyper-v
    [单片机] ESP8266 开机自动透传
    [操作系统] 死锁预防和死锁避免
    [linux] 手机Deploy linux 桌面中文乱码
    XHTML基础
    JDBC_c3p0连接池
  • 原文地址:https://www.cnblogs.com/nafio/p/9137201.html
Copyright © 2020-2023  润新知