跳转到内容

GLSL 编程/逐片段操作

来自维基教科书,开放的书籍,开放的世界

逐片段操作是 OpenGL (ES) 2.0 管线 的一部分,它包含一系列测试和操作,这些操作可以在片段着色器生成的片段颜色写入帧缓冲区中的对应像素之前修改片段颜色。如果任何测试失败,片段将被丢弃。(此规则的例外是模板测试,它可以配置为即使片段未通过模板测试和/或深度测试,也可以更改像素的模板值。)

在逐片段操作的概述中,蓝色方块代表数据,灰色方块代表可配置的逐片段操作。


片段数据(颜色和深度) 片段着色器的输出
像素所有权测试 应用程序无法自定义
剪刀测试 如果片段位于指定(剪刀)矩形之外,则测试失败
Alpha 测试 仅在 OpenGL 中,不在 OpenGL ES 2.x 中;结果取决于片段的 alpha 值(不透明度)、参考 alpha 值和配置的 alpha 测试
模板测试 结果取决于对应像素处的模板缓冲区中的值和配置的模板测试
深度测试 结果取决于片段的深度、对应像素处的深度缓冲区中的深度以及配置的深度测试
混合 结果取决于片段颜色(包括其不透明度)、帧缓冲区中对应像素的颜色以及配置的混合方程
抖动 通常无法由应用程序自定义
逻辑运算 仅在 OpenGL 中,不在 OpenGL ES 2.x 中;结果取决于片段的颜色、帧缓冲区中对应像素的颜色以及配置的逻辑(按位)运算
帧缓冲区(颜色、深度和模板值) 可以禁用对帧缓冲区的写入,针对各个通道


具体的逐片段操作

[编辑 | 编辑源代码]

一些逐片段操作尤为重要,因为它们有已知的应用

  • 深度测试用于以正确的遮挡关系渲染不透明的图元(例如三角形)。这是通过将片段的深度与之前渲染的最前面片段的深度(存储在深度缓冲区中)进行比较来完成的。如果片段更远,则深度测试失败,片段将被丢弃。否则,该片段将成为新的最前面片段,其深度将存储在深度缓冲区中。
  • 混合用于通过混合(即合成)片段的颜色与已存储在帧缓冲区中的颜色来渲染半透明图元(玻璃、火焰、耀斑等)。这通常与禁用写入深度缓冲区相结合,以避免半透明图元遮挡其他图元。
  • 模板测试通常用于将渲染限制在屏幕的某些区域,例如镜子、窗口或 3D 场景中更一般的“门户”。它还具有用于某些算法(例如阴影体积)的更高级的用途。

有关特定逐片段操作的更多详细信息可以在特定平台的教程中找到,因为这取决于平台,以及操作是如何配置的。

关于逐片段操作顺序的说明

[编辑 | 编辑源代码]

虽然 OpenGL 的规范对逐片段操作施加了特定的顺序,但 GPU 可以更改这些操作的顺序,只要这样做不会改变结果即可。事实上,GPU 会在尽可能的情况下甚至在执行片段着色器之前执行许多测试。在这种情况下,如果片段未通过其中一项测试,则不会为该片段执行片段着色器。(一个例子是所谓的“早期深度测试”。)这可以带来显著的性能提升。

逐片段操作的可编程性

[编辑 | 编辑源代码]

逐片段操作通常是可配置的,但不可编程的,即可以以某些方式配置各种测试,但不能编写程序来计算测试。然而,这种情况正在改变。例如,OpenGL ES 2.0 不提供 alpha 测试,因为可以通过片段着色器中的条件丢弃操作来实现相同的功能,这实际上是可编程的 alpha 测试。另一个例子是(多厂商)OpenGL ES 扩展 GL_EXT_shader_framebuffer_fetch,它提供可编程混合。(此扩展在大多数(如果不是全部)iOS 6 设备上受支持。在 iOS 6 的测试版中,该扩展称为 GL_APPLE_shader_framebuffer_fetch。在配备 Nvidia Tegra 芯片的设备上,类似的扩展 GL_NV_shader_framebuffer_fetch 通常可用。)

进一步阅读

[编辑 | 编辑源代码]

OpenGL ES 2.0 的逐片段操作在“Khronos OpenGL ES API 注册表”中提供的“OpenGL ES 2.0.x 规范”的第 4 章中详细定义。

Addison-Wesley 出版了 Aaftab Munshi、Dan Ginsburg 和 Dave Shreiner 合著的书籍“OpenGL ES 2.0 编程指南”的第 11 章给出了更易懂的描述(参见 其网站)。


< GLSL 编程

除非另有说明,否则此页面上的所有示例源代码均归属公有领域。
华夏公益教科书