从碎片器返回浮动

时间:2016-07-25 15:00:07

标签: c++ opengl glsl shader fragment-shader

对于应用程序,我需要创建网格的深度图像。基本上我想要一个图像,每个像素告诉摄像机中心和交叉点之间的距离。我选择使用OpenGL执行此任务,因此大多数计算可以在GPU而不是CPU上完成。

这是我的顶点着色器代码。它计算交叉点的真实世界坐标并将坐标存储在varying vec4中,以便我可以在片段着色器中访问它。

varying vec4 verpos;
void main(void)
{
    gl_Position = ftransform();
    verpos = gl_ModelViewMatrix*gl_Vertex;
}

这里是片段着色器的代码。在片段着色器中,我使用这些坐标来计算使用毕达哥拉斯到原点(0,0,0)的欧里德距离。为了能够访问CPU上的计算值,我的计划是使用gl_FragColor将距离存储为颜色,并使用glReadPixels(0, 0, width, height, GL_RED, GL_FLOAT, &distances[0]);

提取颜色值
varying vec4 verpos;
void main() 
{ 
    float x = verpos.x;
    float y = verpos.y;
    float z = verpos.z;

    float depth = sqrt(x*x + y*y + z*z) / 5000.0;
    gl_FragColor = vec4(depth, depth, depth, 1.0);
}

问题是,我仅以0.003921569=1/255)的精度收到结果。 结果值包含例如0.364705890, 0.364705890, 0.364705890, 0.364705890, 0.368627459, 0.368627459, 0.368627459。一行中的大多数值完全相同,然后跳跃为1/255。 因此,介于gl_FragColorglReadPixels之间的某个位置,OpenGL将浮点数转换为8位,然后将它们转换回浮点数。

如何在不丢失精度的情况下将距离值提取为浮点值?

1 个答案:

答案 0 :(得分:1)

将R32F或R16F纹理附加到FBO并渲染到它。然后使用docker run -Pd -p 8080:8080 -p 8001:8001 --name jbpm-workbench docker.io/jboss/jbpm-workbench-showcase 提取像素,就像使用glGetTexImage2D()一样。