我有一个批量渲染管道,可以将一堆四边形上载到OpenGL。这些将渲染到FBO。当然,其中一个附件是视觉输出,另一个是深度,允许进行后处理等。然而,第三个附件旨在存储用于拾取的对象ID,其风格与此处解释的类似。
有个小问题。我希望一些渲染项目对拾取是"透明的"。从本质上讲,有些东西(粒子或视觉装饰或其他什么(本身是不可拾取的,但不应阻止拾取它们后面的对象。
如何才能做到这一点?网络搜索表明,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;
}
}
丢弃片段是二进制的;它要么被丢弃(连同它的所有结果(,要么被接受。
您也不能对非标准化的整数图像格式进行混合。混合仅适用于浮点类型(包括规范化整数(。
您最好的选择是只使用浮动图像格式作为索引。将整数投射到着色器,然后使用混合来启用/禁用它。这将需要在着色器中写入vec4
,以便可以写入适当的alpha值。请注意,仅仅因为您正在编写vec4
并不意味着图像格式必须有4个组件;它仍然可以有一个组件,混合应该可以工作(只要你只使用源alpha(。