Skip to content

逐样本处理 (Per-Sample Processing)

逐样本处理是 OpenGL 渲染管线中的一个阶段,在此阶段中,片元着色器输出的片元被处理,其结果数据被写入各种缓冲区。

提前操作 (Early Operations)

规范规定逐样本处理操作在片元着色器执行后进行。然而,在某些情况下,这些操作可以在片元着色器执行之前完成。以下操作可以在特定条件下提前执行(按顺序):

  • 像素所有权测试 (Pixel Ownership Test)
  • 裁剪测试 (Scissor Test)
  • 模板测试 (Stencil Test)
  • 深度测试 (Depth Test)
  • 遮挡查询更新 (Occlusion Query Updating)

提前测试的条件

这些操作可以在两种情况下提前执行:

  1. 隐式优化:OpenGL 检测到片元着色器的执行不会干扰这些测试
  2. 显式请求:片元着色器通过 layout(early_fragment_tests) 显式请求提前执行

如果通过显式请求启用提前测试,所有这些操作将首先执行,且对这些缓冲区的所有写入也将首先发生。因此,在片元着色器中影响这些写入的操作将被有效忽略。例如,在提前测试的片元着色器中执行 discard 不会阻止深度或模板值的更新,也不会阻止遮挡查询计数器的增加。

从 OpenGL 4.2 或 ARB_shader_image_load_store 扩展开始,像素所有权测试和裁剪测试必须始终提前执行。

像素所有权测试 (Pixel Ownership Test)

由于默认帧缓冲区由 OpenGL 外部资源拥有,默认帧缓冲区的某些像素可能不被 OpenGL 拥有,因此 OpenGL 无法写入这些像素。指向这些像素的片元会在管线此阶段被丢弃。

典型场景

如果渲染的窗口被另一个窗口部分遮挡,被遮挡的像素不再由 OpenGL 拥有,因此无法通过所有权测试。覆盖这些像素的任何片元都会被丢弃。这也包括帧缓冲区清除操作。

此测试影响对默认帧缓冲区的渲染。当渲染到帧缓冲区对象(FBO)时,所有片元都通过此测试。

裁剪测试 (Scissor Test)

可以指定目标帧缓冲区的一个矩形区域作为唯一有效的渲染区域。所有指向此矩形外像素的片元都会在此阶段被丢弃。

多重采样操作 (Multisample Operations)

详见多重采样相关文档。

模板测试 (Stencil Test)

启用模板测试后,可以根据片元的模板值与当前模板缓冲区中存储的模板值之间的位运算结果来丢弃片元。这允许用户在一个渲染通道中设置模板值,然后根据此模式有条件地剔除片元。

深度测试 (Depth Test)

启用深度测试后,可以根据片元的深度值与当前深度缓冲区中存储的深度值之间的条件测试结果来剔除片元。这对于使几何体被其他几何体遮挡非常有用。较近的几何体设置深度值,使用适当的深度测试条件来遮挡其后面的任何片元。

遮挡查询更新 (Occlusion Query Updating)

如果片元通过了深度测试(仅检查通过深度测试),则此时活动的遮挡查询将认为有一个片元通过。因此:

  • 如果是 GL_SAMPLES_PASSED 查询,计数器将递增
  • 如果是布尔查询,布尔值将设置为 GL_TRUE

注意

到达此点并不保证任何特定值将被写入任何特定缓冲区。写入掩码可以关闭对特定缓冲区的写入,帧缓冲区的绘制缓冲区设置可以有效地忽略一个或多个片元值,甚至帧缓冲区对象可能完全为空,没有附加任何图像。

混合 (Blending)

片元中的每种颜色可以与片元将要写入的缓冲区中的相应像素颜色组合。此混合操作的结果将被写入。

如果读取的图像处于 sRGB 颜色空间且 GL_FRAMEBUFFER_SRGB 当前已启用,则用于混合操作的颜色将在与片元颜色混合之前转换为线性 RGB。

sRGB 转换

如果 GL_FRAMEBUFFER_SRGB 当前已启用,则对于每个被写入具有 sRGB 颜色空间图像格式的图像的片元颜色,颜色的 RGB 分量将从线性转换为 sRGB。

抖动 (Dithering)

当颜色被写入帧缓冲区图像时,图像的精度可能低于传入值。这仅在将浮点值写入归一化整数图像格式时才有影响。对于给定的图像格式精度和给定的颜色值,最多有两种可用于该颜色的颜色:向上舍入和向下舍入的颜色。

禁用抖动时,选择哪种颜色是实现定义的,但不允许依赖于片元在窗口中的位置。对于低精度图像格式,浮点值的细微渐变会呈现为几个明显且分离的色带。

抖动可用于避免这种色带。抖动算法通过根据片元位置变化选择的颜色来模拟平滑渐变。因此,如果颜色值介于两种可表示颜色之间,则一半像素将是一种颜色,另一半是另一种颜色。

抖动通过启用 GL_DITHER 来开启,默认启用。

逻辑操作 (Logic Operations)

片元颜色可以通过对它们执行布尔运算来与帧缓冲区中的相应值有条件地组合。这会覆盖混合,并且仅适用于写入整数(归一化或非归一化)图像格式的颜色,且不使用 sRGB 写入 sRGB 图像。

写入掩码 (Write Mask)

对特定缓冲区的写入可以被屏蔽。这还允许屏蔽这些写入的特定分量,例如只更新红色颜色分量。每个输出缓冲区可以有自己的掩码。

基于 OpenGL Wiki 的本地化项目