对于应用程序,我需要创建网格的深度图像。基本上我想要一个图像,每个像素告诉摄像机中心和交叉点之间的距离。我选择使用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_FragColor
和glReadPixels
之间的某个位置,OpenGL将浮点数转换为8位,然后将它们转换回浮点数。
如何在不丢失精度的情况下将距离值提取为浮点值?
答案 0 :(得分:1)
将R32F或R16F纹理附加到FBO并渲染到它。然后使用docker run -Pd -p 8080:8080 -p 8001:8001 --name jbpm-workbench docker.io/jboss/jbpm-workbench-showcase
提取像素,就像使用glGetTexImage2D()
一样。