目录
- 一、说明
- 二、逻辑运算
- 三、行动
- 四、写入掩码
- 6.1 颜色掩码
- 6.2 深度mask
- 6.3 模板mask
一、说明
对于渲染管道的混合方案,需要以种种不同混合方案,其中混合的方式用逻辑运算实现。其次,在混合颜色的时候,还有掩码过滤器,本文将介绍这些颜色混合操作。
二、逻辑运算
OpenGL 渲染管道
逻辑操作是在片段的颜色值和帧缓冲区中与该特定片段颜色相对应的颜色值之间应用的每样本处理操作。逻辑运算是对表示颜色的位模式执行的布尔运算。
若要激活逻辑操作,必须启用GL_COLOR_LOGIC_OP。每当启用逻辑操作时,都会禁用所有混合操作。
由于逻辑运算是按位布尔运算,因此有时此类运算是不合适的。这些属性由附加到与该片段颜色相对应的帧缓冲区的图像属性定义。启用逻辑操作后,仅当满足以下所有条件时,才会对特定颜色缓冲区执行逻辑操作:
帧缓冲图像使用整数图像格式(规范化或非规范化)。
sRGB 渲染处于禁用状态,或者如果启用,帧缓冲图像的图像格式不在 sRGB 色彩空间中。
如果这些条件中的任何一个失败,则该特定颜色缓冲区将不会对其执行逻辑操作。渲染操作中的其他缓冲区可能仍通过这些测试,并且将对它们执行逻辑操作。
三、行动
有许多不同的逻辑操作可用。请注意,与 Blending 不同,OpenGL 逻辑操作不能对不同的片段颜色执行单独的操作。所有片段颜色(不能使用逻辑运算的片段颜色除外,如上所述)都将使用相同的操作。
要使用的特定操作由以下函数设置:
void glLogicOp(GLenum 操作码);
操作码定义要使用的操作(默认值为 GL_COPY。下表列出了可用的逻辑运算及其结果。逻辑运算是按组件单独执行的。
片段颜色的分量值称为 S;帧缓冲图像中的分量值称为 D。“&”是按位,“|”是按位,或者,“^”是按位 xor,~ 是按位否定。
操作码 | 生成的操作 |
---|---|
GL_CLEAR | 0 |
GL_SET | 1 |
GL_COPY | S |
GL_COPY_INVERTED | ~S |
GL_NOOP | D |
GL_INVERT | ~D |
GL_AND | S&D公司 |
GL_NAND | ~(S&D ) |
GL_OR | S |
GL_NOR | ~(S |D) |
GL_XOR | S ^ D |
GL_EQUIV | ~(S ^ D) |
GL_AND_REVERSE | S & ~D |
GL_AND_INVERTED | ~S&D |
GL_OR_REVERSE | S|~D |
GL_OR_INVERTED | ~S |D |
四、写入掩码
写入掩码是渲染管线的一部分,用于允许或阻止将颜色、深度或模具组件写入当前帧缓冲区。
片段可以包含多个颜色值、深度值和模具值。除模具外,所有模具都可以由片段着色器生成。经过各种测试操作后,可以将片段的值写入当前帧缓冲区中的样本。写入屏蔽状态可以防止写入数据的某些组件。
掩码状态会影响修改当前帧缓冲区的以下操作:
所有绘图命令。
帧缓冲清除调用 glClear 和 glClearBuffer。
注意:这不适用于影响恰好是当前帧缓冲区一部分的图像的操作。例如,如果使用图像加载存储来修改图像的数据,则写入掩码不会影响该写入,即使该图像也是当前帧缓冲对象的一部分(当然,尝试以两种方式写入同一图像也会产生未定义的行为)。写入掩码仅适用于通过当前帧缓冲区的写入操作。
尽管掩码仅适用于对帧缓冲区的写入,但掩码状态不是帧缓冲状态。因此,它不是 Framebuffer 对象或默认 Framebuffer 的一部分。绑定新的帧缓冲区不会影响掩码。
6.1 颜色掩码
片段着色器输出的颜色可以被遮罩。每个单独的颜色组件(R、G、B 和 A)都有一个单独的蒙版。因此,可以防止写入某些颜色组件。
由 glDrawBuffers 函数定义的每个单独的颜色缓冲区都有一个单独的掩码。
若要为特定绘制缓冲区设置掩码,请使用 glColorMaski 函数:
void glColorMaski(GLuint buf, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
buf 参数指定要为其设置蒙版的颜色缓冲区。这可以是 [0, GL_MAX_DRAW_BUFFERS) 范围内的任何值。其他值设置为 GL_TRUE 以启用写入该组件,GL_FALSE设置为禁用写入该组件。
函数 glColorMask 可用于设置所有绘制缓冲区的掩码。这对于在所有输出缓冲区上快速重新启用写入掩码非常有用。
6.2 深度mask
深度缓冲区写入可以屏蔽,从而防止深度缓冲区更新。这对于实现透明度很有用。遮罩由以下函数控制:
void glDepthMask(GLboolean flag);
将 flag 设置为 GL_TRUE 表示写入深度。
6.3 模板mask
模板写入遮罩的工作方式略有不同,有两种方式。首先,Stencil Buffer 始终是一个无符号整数(具有一定的位深度),因此此处的掩码是一个实际的位域,而不是简单的开/关。
另一个区别是三角形的两条边的模板测试可能不同。因此,可以为任一侧设置模板写入掩码,也可以同时为两侧设置模板。
要设置模具位掩码,请使用以下函数:
void glStencilMaskSeparate(GLenum face, GLuint mask);
面确定要设置的模具位掩码面。可以GL_FRONT、GL_BACK或GL_FRONT_AND_BACK同时设置两边的位掩码。在掩码中设置的位是唯一会受到任何后续渲染命令影响的模具位。
glStencilMask 函数可用作GL_FRONT_AND_BACK的简写。