16位OpenGL 3D纹理内的12位值奇怪精度损失

时间:2013-07-24 14:37:19

标签: opengl gpu precision

我的3D体积值在[-1024; 3071。让我们称之为input。我需要以这种方式使用OpenGL处理​​这些值,1对应于值3071而0映射到-1024。由于12位足以覆盖4096个可能值的范围,因此我创建了一个内部格式为GL_TEXTURE_3D的{​​{1}}对象。在将纹理数据作为GL_INTENSITY16值数组上传之前,我确实执行左移4位以建立所需的映射,如上所述:

uint16_t

然后我按照这些步骤沿着x方向的线对纹理的值进行采样,使得支持点的值始终被命中,这意味着不需要插值。为了执行采样,将点绘制到帧缓冲对象,该对象使用纹理对象const std::vector< signed short >& inputBuffer = input.buffer(); std::vector< uint16_t > buffer( inputBuffer.size() ); for( unsigned int i = 0; i < inputBuffer .size(); ++i ) { buffer[ i ] = static_cast< uint16_t >( ( inputBuffer[ i ] + 1024 ) << 4 ); } glBindTexture( GL_TEXTURE_3D, volumeTextureID ); glTexImage3D( GL_TEXTURE_3D, 0, GL_INTENSITY16 , size.x, size.y, size.z , 0, GL_RED, GL_UNSIGNED_SHORT, &buffer.front() ); 作为其colorBufferID颜色缓冲区:

GL_RGBA16F

如上所述,上述函数是针对不同的float gpuSampleAt( float x, float y, float z ) { bindFramebufferObject(); glBindTexture( GL_TEXTURE_3D, volumeTextureID ); glBegin( GL_POINTS ); glTexCoord3f( x, y, z ); glVertex3f( 0, 0, 0 ); glEnd(); unbindFramebufferObject(); float intensity; glBindTexture( GL_TEXTURE_2D, colorBufferID ); glGetTexImage( GL_TEXTURE_2D, 0, GL_RED, GL_FLOAT, &intensity ); return intensity * 4095 - 1024; } 值执行的。获得的强度相对于它们的x位置绘制:

x

在CPU上完成同样的操作,这非常简单。绘图结果如下图所示 - 由CPU获得的样本用蓝色曲线显示,通过OpenGL获得的样本用红色显示:

Plot of the obtained data - blue: samples obtained by CPU - red: those obtained by OpenGL

为什么结果不一样?

0 个答案:

没有答案