从零开始游戏开发——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中了。
本文来自博客园,作者:毅安,转载请注明原文链接:https://www.cnblogs.com/primarycode/p/16704604.html,文章内容同步更新微信公众号:“游戏开发实战”或“GamePrimaryCode”