如何使用 glReadPixels 读取浮点数据
Posted
技术标签:
【中文标题】如何使用 glReadPixels 读取浮点数据【英文标题】:How can I read float data with glReadPixels 【发布时间】:2013-06-01 15:54:31 【问题描述】:几天来,我一直在尝试使用 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。什么可能导致这种情况?
【问题讨论】:
【参考方案1】:这是由于您将浮点值存储在规范化的整数中,然后将其读回并将其转换为浮点值。
除非您使用framebuffer object,否则您当前的帧缓冲区很有可能就是您从 OpenGL 上下文中得到的。这可能使用GL_RGBA8
作为image format。这是每个通道 8 位,无符号和标准化,存储为整数。所以你写入的浮点值被钳制在 [0, 1] 范围内,然后通过乘以 255 并四舍五入转换为整数,然后存储。
当你把它作为浮点数读回时,转换是相反的:整数值被转换成浮点数,除以 255,然后返回。
0.02 * 255 = 5.1 ~= 5
5 / 255 = 0.0196
这就是你得到的回报。
如果您想从片段着色器写入一个浮点值,并且实际上从您读回的内容中获得超过 2-3 位的精度,那么您需要渲染到包含具有合理图像的图像的 FBO格式。例如浮点图像(GL_R16F
或 GL_R32F
,因为您只写入一个数据通道)。
【讨论】:
这是有道理的。谢谢。以上是关于如何使用 glReadPixels 读取浮点数据的主要内容,如果未能解决你的问题,请参考以下文章
保存使用 glReadPixels 读取的图像,其中 alpha 值不是一