3
\$\begingroup\$

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 

EDIT

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?

\$\endgroup\$
  • \$\begingroup\$ Maybe a problem of glsl float precision? \$\endgroup\$ – dnk drone.vs.drones Oct 12 '15 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 Oct 12 '15 at 18:54
  • 1
    \$\begingroup\$ Have you checked if the endianness/byte order changes anything? \$\endgroup\$ – user000user Oct 12 '15 at 19:39
  • \$\begingroup\$ Hm, it might. How would I test this? \$\endgroup\$ – Code Cube Oct 12 '15 at 20:54
  • 2
    \$\begingroup\$ Are you using glVertexAttribIPointer to when setting up this vertex attribute (not glVertexAttribPointer)? \$\endgroup\$ – GuyRT Oct 13 '15 at 10:58
4
\$\begingroup\$

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.

| improve this answer | |
\$\endgroup\$
  • \$\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\$ – ForeverZer0 Apr 26 at 5:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.