OpenGL 在计算着色器中为 GL_TEXTURE_3D 混合颜色

OpenGL mixes colors for GL_TEXTURE_3D in compute shader

我不确定这是否是驱动程序错误,但会发生以下情况:

计算-shader.glsl:

#version 320 es
precision mediump float;

layout(local_size_x = 16, local_size_y = 8, local_size_z = 1) in;
layout(rgba8ui, binding = 0) writeonly uniform mediump uimage2D image;
layout(binding = 1) uniform mediump usampler3D grid;

void main() {
    uint i = gl_GlobalInvocationID.y;
    uint j = gl_GlobalInvocationID.x;

    uvec4 val = texture(grid, vec3(float(i)/480.0,float(j)/640.0,0.5));

    imageStore(image, ivec2(j,i), val);
}

val的颜色通道被完全打乱:

main.cpp:

    glActiveTexture(GL_TEXTURE1);
    glEnable(GL_TEXTURE_3D);
    glBindTexture(GL_TEXTURE_3D, grid_tex_id);
    glTexStorage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 256, 256, 256);
    glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 256, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, grid.data);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

这有什么合理的解释吗?注意:我不想使用 hack val.ragb(如果存在的话)。

layout(binding = 1) uniform mediump usampler3D grid;
...
glTexStorage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 256, 256, 256);

GL_RGBA8 不是整数格式;这是一种 标准化 格式。这意味着它相当于一个浮点格式。所以你应该使用 sampler3D,而不是 usampler3D。或者您应该使用 GL_RGBA_INTEGER 像素传输格式将数据上传为 GL_RGBA8UI 等整数格式。

您可能使用 re-specifying the format in the shader itself 的图像 Load/Store 成功了。你不能用纹理做到这一点。