我有一个批处理渲染管道,可以将一堆四边形上传到 OpenGL。这些被呈现给 FBO。当然,其中一个附件是视觉输出,另一个附件是深度,允许进行后处理等。但是,第三个附件旨在存储用于拾取的对象 ID,其风格与解释的类似 here .
有一个小问题。我希望一些渲染的项目对于拾取来说是“透明的”。本质上,有些东西(粒子或视觉装饰或其他什么)本身是不可拾取的,但不应阻止拾取它们后面的对象。
如何实现这一点?网络搜索表明 glAlphaFunc
可能曾经履行过这个角色,因为我可以将对象 id 打包到具有透明 channel 的纹理中,然后删除我将透明度设置为 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;
}
}
最佳答案
丢弃片段是二进制的;它要么被丢弃(连同其所有结果),要么被接受。
您也无法混合为非标准化整数图像格式。混合仅适用于浮点类型(包括标准化整数)。
最好的选择是为索引使用 float 图像格式。将整数转换到着色器,然后使用混合来打开/关闭它。这需要在着色器中编写一个vec4
,以便您可以编写适当的 alpha 值。请注意,仅仅因为您正在编写 vec4
并不意味着图像格式必须有 4 个组件;它仍然可以有 1 个组件,并且混合应该可以工作(只要您只使用源 alpha)。
关于opengl - 在现代 OpenGL 中,如何避免用无效片段覆盖 FBO 颜色附件中的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63697218/