从零开始游戏开发——3.4 片断处理

  在光栅阶段,除了要通过片断着色程序(OpenGL叫法)着色外,还需要进行裁剪测试、Alpha测试、模板测试、深度测试、混合操作,这些操作在OpenGL、D3D、Vulkan等操作顺序不尽相同,在软件渲染器,片断着色程序是渲染管线的瓶颈所在,因此这里的光栅化之后流程如下,这里的橙色部分任意一条执行失败,都不会继续执行后面操作。

  裁剪测试:用来表示绘制过程定义的一个矩形区域,只有位于这个区域内的像素才会被最终绘制。

  模板测试:模板测试用到了模板缓冲区,可以实现各种特效,有些阴影算法会用到模板。模板缓冲区可进行读写操作,使用启用测试时,首先设定一个参考值和Mask值,在模板测试阶段对当前像素模板缓冲区中的值与Mask按位与后和设置的参考值进行比较,得到比较结果后对模板缓冲区当前像素值执行一些操作,比较结果通过时,继续执行下个阶段。这里的比较操作包含:

    never:比较结果总是返回false。

    always:比较结果总是返回true。

    equal:模板值与参考值相等返回true,否则返回false。

    not equal:模板值与参考值不等返回true,否则返回false。

    less than:模板值小于参考值返回true,否则返回false。

    less or equal:模板值小于等于参考值返回true,否则返回false。

    greater than:模板值大于参考值返回true,否则返回false。

    greater or equal:模板值大于等于参考值返回true,否则返回false。

 对模板值的操作分为三种情况,分别为模板测试不同过,深度测试不通过和模板测试与深度测试均通过。针对这三种情况,模板值可进行以下操作:

    zero:将模板缓冲区的值置为0。

    keep:保持当前模板缓冲区中的数值不变。

    replace:参考值替换模板缓冲区中的值。

    invert:模板缓冲区的值按位取反。

    increment:当前模板缓冲区的值小于最大模板值,则模板值加1。

    decrement:当前模板缓冲区的值大于0,则模板值减1。

   深度测试:深度测试用到了深度缓冲区,即zbuffer。在光栅化时得到的当前待绘制点的1/z值与缓冲区中的值进行比较,如果通过测试,则写深度值,并继续执行下一个操作,这里比较操作与上面模板比较操作相同。这里所以是1/z,是因为前面提到通过透视投影后,z值遇到到[-1,1]区间是非线性的,如果使用z值进行深度测试,将造成摄像机远处的很大范围深度值映射于很小的范围内,从而导致精度缺失,从1/z是线性的,储存1/z则可以解决这个问题。

  Alpha测试:着色Alpha值与设置的值进行比较,只有满足比较结果的才进行下一个阶段,Alpha测试通过条件通栏包括never、always、equal、not equal、less than、 less than or equal、greater than、greater or equal。

  混合:最终颜色值将与FrameBuffer中的颜色值进行混合,计算公式为:finalValue = sourceFactor * sourceValue operation destinationFactor * destinationValue,sourceValue是上个阶段计算出的颜色值,destinationValue是帧缓存中的颜色值,sourceFactor和destinationFactor为混合因子,其代表的值有如下几种:

    One:1

    Zero:0

    SrcColor:源RGB的值

    SrcAlpha:源A值

    DstColor:目标RGB值

    DstAlpha:目标A值

    OneMinusSrcColor:(1,1,1) - SrcColor

    OneMinusSrcAlpha:1- SrcAlpha

    OneMinusDstColor:(1,1,1) - DstColor

    OneMinusDstAlpha:1 - DstAlpha

operation可以有以下几种:

    Add:源结果+目标结果

    Sub:源结果-目标结果

    RevSub:目标结果-源结果

  经过以上几个操作,颜色值就可以写入的Framebufer中了。

posted @ 2022-09-18 16:10  毅安  阅读(123)  评论(2编辑  收藏  举报