OpenGL:从GPU中检索浮点计算结果

时间:2016-03-15 15:46:17

标签: opengl

简而言之

在单个着色器传递中,我在顶点着色器中应用了几个不同的模型变换矩阵,并将结果写入不同的位置矢量。 然后我用Vertex Shader中的不同结果做一些简单的算术。

//Vertex Shader
in layout(location=0) vec3 position;
in layout(location=1) vec3 vertexColor;

...

out vec3 result1;
out vec3 result2;    
out vec3 result3;
out vec3 color;

void main()
{
    gl_Position = transformationMatrix * vec4(position, 1.0);
    vec4 pos1 = transformationMatrix1 * vec4(position, 1.0);
    vec4 pos2 = transformationMatrix2 * vec4(position, 1.0);

    ... 

    result1 = pos1.xyz * pos2.xyz / 0.012313879834;
    result2 = (pos2.xyz + pos1.xyz) * 1.5;
    result3 = ....;

    color = vertexColor;
}

我希望通过片段着色器传递数学的结果(因此值很好地插入颜色)...

// Fragment shader
in vec3 color;

in vec3 result1;
in vec3 result2;
in vec3 result3;

layout(location = 0) out vec4 theColor;
layout(location = 1) out vec3 output1;
layout(location = 2) out vec3 output2;
layout(location = 3) out vec3 output3;

void main()
{   
    theColor = vec4(color, 1.0);
    output1 = result1;
    output2 = result2;
}

...最后读回来,以便我可以继续处理CPU上的数据。我需要读回的数据是精确的(浮点数32),最好不要归一化为[0,1]。

关于这一点,我有几个问题:

  1. 最初我认为可以使用GL_COLOR_ATTACHMENTi来促进这一点,但我还没有弄清楚如何。可能吗?如果是这样,我该怎么做呢?
  2. 自OpenGL 4.2以来使用图像加载/存储功能的解决方案如何?我是否需要注意潜在的陷阱?
  3. 编辑:毕竟我得到它与颜色附件一起使用。请参阅下面的解决方案,对我有用。

1 个答案:

答案 0 :(得分:0)

毕竟找到了一个使用Color Attachments的解决方案。客户端代码如下所示,Shaders不需要任何更改iirc:

void initializeGL()
{
    ....

    // Generate textures.
    glGenTextures(3, textures.data());

    for (GLuint id : textureIds)
    {
        // Bind texture and specify size and nature ...
        glBindTexture(GL_TEXTURE_2D, id);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, m_width, m_height, 0, GL_RGB, GL_FLOAT, nullptr);
    }

    glBindTexture(GL_TEXTURE_2D, 0);

    ....

    // Attach texture images to Framebuffer.
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, otherTextureId, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, textureIds[0], 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, textureIds[1], 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, textureIds[2], 0);

    // Specify color buffers that will be written to.
    const GLenum buffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
    glDrawBuffers(4, buffers);

    ....
}


void renderGL()
{
    ....

    // Copy images into corresponding buffers in the main memory.
    glReadBuffer(GL_COLOR_ATTACHMENT1);        
    glReadPixels(0, 0, m_width, m_height, GL_RGB, GL_FLOAT, texture1.data());
    glReadBuffer(GL_COLOR_ATTACHMENT2);
    glReadPixels(0, 0, m_width, m_height, GL_RGB, GL_FLOAT, texture2.data());
    glReadBuffer(GL_COLOR_ATTACHMENT3);
    glReadPixels(0, 0, m_width, m_height, GL_RGB, GL_FLOAT, texture3.data());

    ....
}

任何反馈仍然会受到赞赏。