0

Many sources recommend using 16-bit vertex/texture coordinates, but all the example code I've seen relies on 32-bit floats.

I've read the extension for 16-bit vertex coordinates, but it doesn't provide any examples of how it can be used.

MatthewScarpino
  • 5,672
  • 5
  • 33
  • 47
  • 1
    Note, that the opengl tag should only be used for desktop OpenGL. Since the extension you provided seems to be for OpenGL-es, you should consider removing the opengl tag. The answer, for example, also cites information that are only partially valid for OpenGL-es (and even then it would make a difference which version since `GL_HALF_FLOAT` only exists since es 3.0). – BDL Jan 10 '17 at 23:14
  • Note that for coordinate data fp16 is actually not normally high enough precision, and you will start to get artefacts on devices with larger screen sizes or larger textures sizes where you start to need the additional precision. Use fp32 data for coordinates (both vertex and texture), and fp16 for non-position attriubutes (normals, color data, etc). – solidpixel Jan 11 '17 at 14:32

2 Answers2

2

16-bit vertex/texture coordinates have been in OpenGL (and ES) since the beginning, without the need for extensions. You can provide the coordinates with GL_SHORT type, which is a signed 16 bit number. You can have the values provided normalized ([-1..1]), if you pass normalized=true when providing them via glVertexAttribPointer. You can then scale them within your vertex shader accordingly (whether they are normalized or not).

See this question for more information.

Community
  • 1
  • 1
MuertoExcobito
  • 9,741
  • 2
  • 37
  • 78
  • This requires the driver to do more work in some cases if the normalization isn't handled natively in the hardware, so if you can upload it directly in the correct format it's likely to be either faster (at best), or at least the same speed but more power efficient (at worst). Never make the GPU do more work per frame than it absolutely has to - that just risks slow applications. – solidpixel Jan 11 '17 at 14:30
  • ... also, note that this isn't a generic solution, it will only work if your object-space coordinates are between +1 and -1. – solidpixel Jan 11 '17 at 14:35
  • @solidpixel it is a generic solution, you only need to add an extra scaling matrix to scale the coordinates into object space (as I said in the answer). In fact, it's the one suggested by the OpenGL wiki (https://www.khronos.org/opengl/wiki/Vertex_Specification_Best_Practices). – MuertoExcobito Jan 11 '17 at 14:58
  • Also, your comments about performance and power make the assumption that there is a hardware fp16 processor on the GPU, which is not always the case. If there isn't usually the fp16 is promoted to an fp32 anyhow, so there would be no difference between using a short. – MuertoExcobito Jan 11 '17 at 15:11
0

The GLM Library GLM library supports half-float types. The prefix used is 'h' so where glm::vec3 is a 3 element vector of floating points values, glm::hvec3 is a 3 element vector of half-floats.

And you also need something like glVertexAttribPointer(..., ..., GL_HALF_FLOAT, GL_FALSE, ..., ...);

See this thread 16-bit floats and GL_HALF_FLOAT

and Small float formats where they say

Half floats

32-bit floats are often called "single-precision" floats, and 64-bit floats are often called "double-precision" floats. 16-bit floats therefore are called "half-precision" floats, or just "half floats".

OpenGL supports the use of half floats in Image Formats, but it also allows them to be used as Vertex Attributes by setting the format component type to GL_HALF_FLOAT.

Community
  • 1
  • 1
Armen Avetisyan
  • 1,140
  • 10
  • 29