计算着色器 OpenGL 4.3 中的 imageLoad glsl 总是 return 0

imageLoad glsl always return 0 in compute shader OpenGL 4.3

我知道还有一个标题完全相同的问题但是那里提供的解决方案不适用于我的情况。

我正在尝试从我的计算着色器访问像素值。但是 imageLoad 函数总是 returns 0.

这是我加载图像的方式:

void setTexture(GLuint texture_input, const char *fname)
{
    // set texture related

    int width, height, nbChannels;
    unsigned char *data = stbi_load(fname, &width, &height, &nbChannels, 0);
    if (data)
    {
        GLenum format;
        if (nbChannels == 1)
        {
            format = GL_RED;
        }
        else if (nbChannels == 3)
        {
            format = GL_RGB;
        }
        else if (nbChannels == 4)
        {
            format = GL_RGBA;
        }
        glActiveTexture(GL_TEXTURE0 + 1);
        gerr();
        glBindTexture(GL_TEXTURE_2D, texture_input);
        gerr();
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        gerr();
        glTexImage2D(GL_TEXTURE_2D, // target
                     0,             // level, 0 means base level
                     format,        // internal format of image specifies color  components
                     width, height, // what it says
                     0,             // border, should be 0 at all times
                     format, GL_UNSIGNED_BYTE, // data type of pixel data
                     data);
        gerr();
        glBindImageTexture(1,             // unit
                           texture_input, // texture id
                           0,             // level
                           GL_FALSE,      // is layered
                           0,             // layer no
                           GL_READ_ONLY,  // access type
                           GL_RGBA32F);

        // end texture handling
        gerr();
        glBindTexture(GL_TEXTURE_2D, 0); // unbind
    }
    else
    {
        std::cout << "Failed to load texture" << std::endl;
    }
    stbi_image_free(data);
}

下面是shader中的相关声明和调用代码:


layout(rgba32f, location = 1, binding = 1) readonly uniform image2D in_image;

struct ImageTexture
{
    int width;
    int height;
};

vec3 imageValue(ImageTexture im, float u, float v, in vec3 p)
{
    u = clamp(u, 0.0, 1.0);
    v = 1 - clamp(v, 0.0, 1.0);
    int i = int(u * im.width);
    int j = int(v * im.height);

    if (i >= im.width)
        i = im.width - 1;

    if (j >= im.height)
        j = im.height - 1;

    vec3 color = imageLoad(in_image, ivec2(i, j)).xyz;

    if (color == vec3(0))
        color = vec3(0, u, v); // debug 

    return color;
}

我看到的是绿色渐变,而不是图像的内容,这意味着我的调试代码已生效。

纹理的内部格式与glBindImageTexture or the format argument is not a valid enumerator constant, when the two-dimensional texture image is specified, because format is used twice, for the internal format and the format (see glTexImage2D处指定的格式不匹配):

glTexImage2D(GL_TEXTURE_2D, // target
                0,             // level, 0 means base level
                format,        // internal format of image specifies color
                // components
                width, height, // what it says
                0,             // border, should be 0 at all times
                format, GL_UNSIGNED_BYTE, // data type of pixel data
                data);

glBindImageTexture 格式 参数是 GL_RGBA32F:

glBindImageTexture(1,             // unit
                    texture_input, // texture id
                    0,             // level
                    GL_FALSE,      // is layered
                    0,             // layer no
                    GL_READ_ONLY,  // access type
                    GL_RGBA32F);

因此,内部格式必须是GL_RGBA32F。可能的 fomratGL_RGBA:

glTexImage2D(GL_TEXTURE_2D, // target
                0,             // level, 0 means base level
                GL_RGBA32F,        // internal format of image specifies color
                // components
                width, height, // what it says
                0,             // border, should be 0 at all times
                GL_RGBA, GL_UNSIGNED_BYTE, // data type of pixel data
                data);