I have packed several values needed for shading a particular vertex into a single 32-bit uint. In the shader, it is unpacked like this:

vec3 color;
uint vertexData = data;
float sunlight, artificialLight;
bool occlusion;

artificialLight = float(vertexData & 31u);
vertexData = vertexData >> 5;
sunlight = float(vertexData & 31u);
vertexData = vertexData >> 5;
occlusion = bool(vertexData & 1u);
vertexData = vertexData >> 1;
color.b = float(vertexData & 127u);
vertexData = vertexData >> 7;
color.g = float(vertexData & 127u);
vertexData = vertexData >> 7;
color.r = float(vertexData & 127u);

The color produced by this extraction is much different from the originally intended color. For example:

130, 245, 90 --> 78, 125, 249   (These values are not exact)

I took the code and put it into my main c++ program and ran it with a debugger. It showed the right values.

130, 245, 90 --> 130, 245, 90 


I have taken a uint produced by my compressor and directly inputted it into my shader like this

vertexData = 2179293184;

Every vertex is shaded with the color of green this value corresponds to. So apparently, there is something going wrong with the transmission of the values. What might be causing this?

  • \$\begingroup\$ Maybe a problem of glsl float precision? \$\endgroup\$ Commented Oct 12, 2015 at 18:35
  • \$\begingroup\$ I don't think it is, because I am performing all the bit shifting and bitwise logic with unsigned integers, then converting it to a float after I have done that. \$\endgroup\$
    – Code Cube
    Commented Oct 12, 2015 at 18:54
  • 1
    \$\begingroup\$ Have you checked if the endianness/byte order changes anything? \$\endgroup\$ Commented Oct 12, 2015 at 19:39
  • \$\begingroup\$ Hm, it might. How would I test this? \$\endgroup\$
    – Code Cube
    Commented Oct 12, 2015 at 20:54
  • 2
    \$\begingroup\$ Are you using glVertexAttribIPointer to when setting up this vertex attribute (not glVertexAttribPointer)? \$\endgroup\$
    – GuyRT
    Commented Oct 13, 2015 at 10:58

1 Answer 1


I suspect your vertex data is being converted to float (and back again).

You should use glVertexAttribIPointer to upload integer vertex data without converting to floating point. From the documentation:

For glVertexAttribPointer, if normalized is set to GL_TRUE, it indicates that values stored in an integer format are to be mapped to the range [-1,1] (for signed values) or [0,1] (for unsigned values) when they are accessed and converted to floating point. Otherwise, values will be converted to floats directly without normalization.

For glVertexAttribIPointer, only the integer types GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT are accepted. Values are always left as integer values.

  • \$\begingroup\$ I can't tell you how long I suffered trying to figure out why my bit shifting was not working in a shader, and the solution was simply using the proper function. I naively thought that glVertexAttribPointer was appropriate for integers as well. This has saved me so much trouble, thank you, even if the answer is old. \$\endgroup\$ Commented Apr 26, 2020 at 5:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .