2

几天来,我一直在尝试使用glReadPixels.

我的cpp代码:

//expanded to whole screen quad via vertex shader
glDrawArrays( GL_TRIANGLES, 0, 3 );

int size = width * height;
GLfloat* pixels = new GLfloat[ size ];
glReadPixels( 0, 0, width, height, GL_RED,  GL_FLOAT, pixels );

pixelVector.resize( size );
for ( int i = 0; i < size; i++ ) {
    pixelVector[i] =  (float) pixels[i];
}

和我的着色器代码:

out float data;

void main()
{  
  data = 0.02;
}

奇怪的是,我得到 0.0196078 作为输出。但是当数据为 0.2 时,一切都很好。如果数据为 0.002,则全为 0。什么可能导致这种情况?

4

1 回答 1

5

这是由于您将浮点值存储在规范化整数中,然后将其读回并将其转换为浮点值。

除非您使用的是framebuffer object,否则您当前的 framebuffer 很可能就是您从 OpenGL 上下文中得到的。这可能GL_RGBA8用作图像格式。这是每个通道 8 位,无符号和标准化,存储为整数。所以你写的浮点值被钳制在 [0, 1] 范围内,然后通过乘以 255 并四舍五入转换成整数,然后存储。

当您将它作为浮点数读回时,转换是相反的:整数值被转换为浮点数,除以 255,然后返回。

0.02 * 255 = 5.1 ~= 5

5 / 255 = 0.0196

所以这就是你得到的。

If you want to write a floating-point value from your fragment shader and actually get more than 2-3 digits of precision from what you read back, then you need to be rendering to an FBO that contains images with a reasonable image format. Such as floating-point images (GL_R16F or GL_R32F, since you're only writing one channel of data).

于 2013-06-01T16:17:13.413 回答