Using GL_HALF_FLOAT for vertex data

I am using an FBO created from the following texture definition:

glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, GL_RG16F, 1920, 1080, 0, GL_RG, GL_HALF_FLOAT, NULL );
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, texture/*generated earlier and bound*/, 0 );

Then I read the FBO data into a VBO:

glBindBuffer( GL_PIXEL_PACK_BUFFER_ARB,  vbo );
glReadPixels( 0, 0, 1920, 1080, GL_RG, GL_HALF_FLOAT, NULL );
glBindBuffer( GL_PIXEL_PACK_BUFFER_ARB, 0 );

Now use vbo to render:

glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER_ARB, vbo);
glVertexPointer ( 2, GL_HALF_FLOAT, 0, 0 ); // tried GL_ARB_half_float_vertex as well

It does render but with accuracy errors. I traced it back to the values seem to quantize to integers beginning at x = 1024. 1023.5 is fine. When I set 1024.5 it comes out as 1024. I thought this might be some sort of issue with the FBO half float being hinted as an image rather than vertex data but I am not sure what do do with that thought.

appreciate any help,
David Patrick Farmer

Half-floats only get about 3.31 decimal digits of precision. These sorts of rounding issues are what you signed up for when you choose to use them.

The point is that there is no decimal precision after 1023. As I understand it there should be at least 3.31 decimal digits of precision to max value −32,768.xxx to 32,767.xxx correct?

Also, when I use 16bit floats in Metal I do not have this issue. I must be doing something wrong in OpenGL, I just don’t know what it is.

Remember: floating point values use scientific notation. 1023 in scientific notation is 1.023x103. It’s in the mantissa of that value (the 1.023) part where you get the “3.31 decimal digits of precision”. So you’re only guaranteed “1.02”, with the rest being the “.31” digits.

“Decimal digits” here doesn’t mean “digits past the decimal”; it means “digits in decimal form”. After all, IEEE-754 defines floats in binary, not decimal. The number of binary digits you get in 16-bit floats is 9. That’s why the number of digits in decimal is a fraction, even though you cannot really have a fraction of a digit.

I understand. Moving to a tiled float renderer.
Thank you for your explanation.

David Patrick Farmer