需要以合理的精度创建自定义数据2D纹理

时间:2015-06-01 10:16:32

标签: c++ opengl

想法

我需要创建一个2D纹理,以获得合理精确的浮点值(我的意思是至少与glsl mediump float一样精确)。我想在其中存储每个像素与相机的距离。我没有想要GL Zbuffer到近平面的距离,只有我自己可爱的自定义数据:>

问题/我尝试了什么

  • 通过使用标准纹理作为颜色附件,我没有获得足够的精度。或许我错过了什么?

  • 通过使用深度附件纹理GL_DEPTH_COMPONENT32,我得到了近距离平面的夹紧 - 垃圾。

所以看起来我不习惯使用深度附件,即使他们似乎最终持有更高的精度。那么有没有办法让标准纹理具有mediump float精度?

我觉得奇怪的是,OpenGL没有任意数据的通用容器。我的意思是自定义位深度。或许我又错过了一些东西!

3 个答案:

答案 0 :(得分:1)

您可以使用浮点纹理而不是RGBA纹理,每像素8位。但是,对这些设备的支持取决于您要支持的设备,尤其是旧的移动设备缺乏对这些格式的支持。

GL_RGBA16F(未测试)的示例:

glTexImage2D(GL_TEXTURE_2D, mipmap, GL_RGBA16F, mipmapWidth, mipmapHeight, GL_RGBA, GL_HALF_FLOAT, null);

现在,您可以手动将数据存储在片段着色器中。但是根据你的MVP仍然会发生钳位。您还需要将数据传递给片段着色器。

还有32位格式。

答案 1 :(得分:1)

纹理格式有许多选项可以提供超过8位的组件精度。

如果您的值处于预定义的范围内,这意味着您可以轻松地将值映射到[0.0,1.0]间隔,则标准化的16位格式是您的最佳选择。对于单个组件纹理,格式为GL_R16。您可以使用以下命令分配此格式的纹理:

glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, 512, 512, 0, GL_RED, GL_UNSIGNED_SHORT, NULL);

有两种,三种和四种组件的匹配格式(GL_RG16GL_RGB16GL_RGBA16)。

如果您需要更大范围的值不容易约束,浮动纹理会变得更具吸引力。对1个组件纹理的相应调用是:

glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, 512, 512, 0, GL_RED, GL_HALF_FLOAT, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 512, 512, 0, GL_RED, GL_FLOAT, NULL);

同样,有2个,3个和4个组件的匹配格式。

浮动纹理的优点在于,仅基于用尾数和指数编码的浮点值的性质,它们可以覆盖很宽的范围。这是以较低的精度为代价的。例如,GL_R16F为您提供11位精度,而GL_R16为您提供完整的16位。当然GL_R32F为您提供了足够的精度(24位)和宽范围,但它使用了两倍的存储空间。

答案 2 :(得分:0)

与C API相比,您可能更容易在GLSL中完成此操作。但是,任何自定义深度缓冲区都将始终如一地慢于OpenGL提供的缓冲区。不要指望它能够实时运行。

如果您的目标是访问摄像机中任何片段的原始距离,请记住深度缓冲区值为z / w,其中z是距离近平面的距离,w是距摄像机的距离。因此,可以以可接受的精度快速提取。但是,您仍然面临原始问题:摄像机和近平面之间的碎片不在深度缓冲区中。