OpenGL中的2遍渲染系统使用的MRT着色器绑定到2个帧缓冲纹理 tex1 和 tex2 。 mrt传递的目标是计算场景中的透支并在聚集传递中将其渲染出来。我使用framebuffer纹理传递结果。
它还有一个非常大的工作ssbo缓冲区(使用固定的屏幕分辨率)并且需要很长时间才能链接,但是我可以使用它来执行 atomicAdds 。我想要完成的是用 uiimage2D 上的 imageAtomicAdd 操作替换它,就像使用mrt pass一样。
问题是imageAtomicAdd的结果总是为零,我希望它会像atomicAdd那样上升。
#version 440 core
layout(early_fragment_tests) in;
// this works fine
layout (location = 0) out vec4 tex1;
layout (location = 1) out vec4 tex2;
// this works fine
layout(std430, binding = 3) buffer ssbo_data
{
uint v[1024*768];
};
// this does not work at all.
uniform volatile layout(r32ui) uimage2D imgCounter;
out vec4 frag_colour;
void main ()
{
ivec2 coords = ivec2(gl_FragCoord.xy);
uint addValue = 1u;
uint countOverdraw1 = atomicAdd(v[coords.x + coords.y * 1024], 1u);
uint countOverdraw2 = imageAtomicAdd(imgCounter, ivec2(0,0), 1u);
memoryBarrier();
// supports 256 levels of overdraw..
float overdrawDepth = 256.0;
vec3 c1 = vec3(float(countOverdraw1+1)/overdrawDepth ,0,1);
vec3 c2 = vec3(float(countOverdraw2+1)/overdrawDepth ,0,1);
tex1 = vec4(c1,1);
tex2 = vec4(c2,1);
frag_colour = vec4(1,1,1,1);
}
从khronos website on image atomic operations我收集到了......
对任何超出边界的纹素的原子操作 绑定的图像将返回0并且不执行任何操作。
..但坐标 ivec2(0,0)将完全在纹理大小的范围内(1024 x 768)。
可能纹理设置不正确?这就是我构建uiimage2D(从管道流拼凑在一起)的方式:
编辑:我根据Nicol Bolas的答案更新代码:设置纹理参数而不是采样器参数
char data[1024*768*4];
glGenTextures(1, &m_Handle);
m_Target = GL_TEXTURE_2D;
glActiveTexture(GL_TEXTURE0+6);
glBindTexture(m_Target,m_Handle);
// updated : a sampler object was bound to the texture, but is now removed
glTexParameteri(m_Target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // updated
glTexParameteri(m_Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // updated
glTexParameteri(m_Target, GL_TEXTURE_WRAP_R, GL_REPEAT); // updated
glTexParameteri(m_Target, GL_TEXTURE_WRAP_S, GL_REPEAT); // updated
glTexParameteri(m_Target, GL_TEXTURE_WRAP_T, GL_REPEAT); // updated
glTexImage2D(m_Target, 0, R32UI, 1024, 768, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, data);
如果我通过gDEBugger GL运行它,我看到"此时纹理数据不可用"虽然'纹理4'纹理的参数被填入并且正确,没有任何纹理参数'和' 0级参数'显示(N / A)。在此时捕获调试器会引发一系列未出现在gDEBugger之外的问题。以下是前几个:
GL_INVALID_OPERATION error generated. The required buffer is missing.
GL_INVALID_ENUM error generated. <pname> requires feature(s) disabled in the current profile.
GL_INVALID_OPERATION error generated. <index> exceeds the maximum number of supported texture units.
GL_INVALID_ENUM error generated. or require feature(s) disabled in the current profile.
GL_INVALID_OPERATION error generated. Can't mix integer and non-integer data
...
我明确强制要求GL 4.4或GL4.4&#39;核心&#39;配置文件,所以我有点困惑,可能是缺少所需的缓冲区的问题。难道它错误地将imgCounter视为帧缓冲区的MRT设置的一部分吗?
答案 0 :(得分:4)
纹理不完整。
请参阅绑定纹理以用于图像加载/存储操作时,不将采样器与其绑定。因此,所有这些glSamplerParameter
调用对纹理的完整性状态都没有意义。
纹理不完整,因为过滤参数为GL_LINEAR
,但纹理是无符号整数格式。在创建整数格式纹理时,您应始终将纹理参数设置为有效值。