ROP(raster operations,光栅操作;在 OpenGL 里也叫 per-fragment operations,逐片元操作)是 片元着色 完成后、写进 帧缓冲 之前要经历的一组逐片元操作。它决定两件事:这个片元有没有资格写进帧缓冲,以及写进去时是直接覆盖还是与已有的颜色合成。
这些操作按固定顺序串联,任何一个测试不通过,片元就被丢弃,后面的步骤不再执行:
| 操作 | 作用 | 典型 API |
|---|---|---|
| 裁剪测试(scissor) | 在视口内再划一个矩形,矩形外的片元丢弃 | glScissor |
| Alpha 测试 | 透明度低于阈值的片元丢弃 | 旧版 glAlphaFunc,现在在着色器里 discard |
| 模板测试(stencil) | 与模板缓冲比较,用来做遮罩、描边、阴影体 | glStencilFunc |
| 深度测试(depth) | 与 深度缓冲 比较,决定遮挡关系 | glDepthFunc |
| 混合(blending) | 把片元颜色与帧缓冲已有颜色按权重合成 | glBlendFunc |
| 逻辑操作(logic op) | 对源/目标像素按位运算(AND、OR、XOR…),“ROP” 这个名字最早就是指它 | glLogicOp |
| 写入掩码(write mask) | 按位屏蔽某些颜色通道不写 | glColorMask |
混合的通用形式是对源颜色与目标颜色分别乘一个因子再相加:
最常见的 alpha 混合取 、,即 ,看起来就是"新颜色按透明度盖在旧颜色上"。
注:操作的先后顺序会影响结果。举例来说,透明片元如果不希望挡住后面的物体,就要在开着混合的同时关闭深度写入(
glDepthMask(GL_FALSE)),并且让半透明物体从远到近绘制。另外在片元着色器里discard会让片元在进入 ROP 之前就被杀掉,也就不会产生深度写入。
GPU 里的 ROP
现代 GPU 把这一阶段的固定功能做成独立的硬件单元,同样叫 ROP(render output unit,渲染输出单元):它负责深度/模板测试、混合,并把最终像素写回显存。显卡规格里写的 “ROP 数量”(比如 64 ROPs)指的就是这种单元的数量,它决定了每个时钟周期能处理并写入多少个像素——填充率(fill rate)的上限同时受它和显存带宽限制。
在早期的 2D 图形里,ROP 专指位块传送(bitblt)时源像素与目标像素之间的布尔组合,比如 Windows GDI 里的 SRCCOPY(直接覆盖)、SRCAND、SRCINVERT(异或)。3D 管线沿用这个称呼,把片元与帧缓冲的合成阶段整体称为光栅操作。Vulkan、Direct3D 12 这类低层 API 已经不再使用 “ROP” 这个词,对应的状态被拆进了管线的深度模板状态与颜色混合状态里。
注:安全领域的 ROP 是 return-oriented programming(返回导向编程)的缩写,和这里的图形管线没有关系,不要混淆。


