在现代 OpenGL 中,如何避免用无效片段覆盖 FBO 颜色附件中的数据?

In modern OpenGL, how do I avoid overwriting data in FBO colour attachments with invalid fragments?

我有一个批量渲染管道,可以将一堆四边形上传到 OpenGL。这些被呈现给 FBO。当然,其中一个附件是视觉输出,另一个是深度,允许 post 处理等。然而,第三个附件用于存储对象 ID 以供选择,其风格与 [=13= 解释的类似].

有个小问题。我想要一些渲染的项目 'transparent' 来挑选。本质上,有些东西(粒子或视觉装饰或其他)本身是不可拾取的,但不应该阻止拾取它们后面的物体。

如何实现?网络搜索表明 glAlphaFunc 可能曾经扮演过这个角色,因为我可以将对象 ID 打包到具有透明通道的纹理中,然后删除我将透明度设置为 0 的所有片段。有点繁琐,但是可行的。但是,这已经贬值了。

针对类似问题的另一个常见建议是使用 discard 关键字。这是行不通的,因为它会删除片段的所有输出元素,而不仅仅是指定的附件。

这里有什么解决办法?我可以用我看不到的混合函数做一些聪明的事情吗?我很困惑。


片段着色器看起来像这样:

#region Fragment

#version 440 core

layout(location = 0) out vec4 colour; // Visual
layout(location = 1) out uint interactLayer; // Picking

in vec2 texCoord;
in flat int texUnit;
in flat uint objectID;

uniform sampler2D[32] u_texData;

void main()
{
    vec4 c1 = fragmentColour * texture(u_texData[texUnit], texCoord);
    
    if (c1.w == 0.0f) { discard; }
    colour = c1;
    
    if (objectID == 0xffffffffu) {
        // Please don't write to interactLayer values,
        // but also please don't discard the 'colour' value.
    }
    else {
        interactLayer = objectID;
    }
}

丢弃片段是二进制的;它要么被丢弃(连同其所有结果)要么被接受。

您也不能对 non-normalized 整数图像格式进行混合。混合仅适用于浮点类型(包括规范化整数)。

最好的办法是为索引使用浮动图像格式。将整数投射到着色器,然后使用混合将其变为 on/off。这将需要在着色器中写入一个 vec4 以便您可以写入适当的 alpha 值。请注意,仅仅因为您正在编写 vec4 并不意味着图像格式必须具有 4 个组件;它仍然可以有 1 个组件并且混合应该可以工作(只要您只使用源 alpha)。