Convert an integer to 4 bytes without bitshift operators This code is applicable to either GLSL or C due to virtually identical syntax. Before GLSL 1.3, bitshift operators were not present and I am aiming for backwards compatibility to GLSL 1.2.

float lut[3] = {256,65536,16777216};


vec4 getBytes(float n)
 {
   vec4 bytes;
   bytes.x = floor(n / lut[2]);
   bytes.y = floor((n- bytes.x*(lut[2]) )/ lut[1]);
   bytes.z = floor((n - bytes.y*(lut[1]) - bytes.x*lut[2] )/ lut[0]) ;
   bytes.w = n - bytes.z*lut[0] - bytes.y*lut[1] - bytes.x*lut[2];
   return bytes;
 }

 float getid(vec4 bytes)
 {
   return bytes.w + bytes.z*lut[0]+ bytes.y*lut[1] + bytes.x*lut[2];
 }


This code will be used to pack a value greater than 8 bits into an 8-bit texture with 4 channels.

I also ported the code to Lua to run a unit test.

 lut = {256,65536,16777216}
 function getBytes(n)

   bytes = {}
   bytes.x = math.floor(n / lut[3]);
   bytes.y = math.floor((n- bytes.x*(lut[3]) )/ lut[2]);
   bytes.z = math.floor((n - bytes.y*(lut[2]) - bytes.x*lut[3] )/ lut[1]) ;
   bytes.w = n - bytes.z*lut[1] - bytes.y*lut[2] - bytes.x*lut[3];
   return bytes
 end

 function getid(bytes)

   return bytes.w + bytes.z*lut[1]+ bytes.y*lut[2] + bytes.x*lut[3]
 end

for i=1,math.pow(2,24),1 do 
  if not (getid(getBytes(i)) == i) then

    print("Fail " .. i)
  end

end
There's not a ton that can be improved here, but:


lut should be made const
Due to implicit promotion, lut can be stored as integers instead of floats. Your expressions should evaluate to the same thing.
Consider representing your lut constants in hexadecimal (0x) format - or as 1 &lt;&lt; x notation.
Your lut doesn't strictly need to be an array; you're not iterating over it or indexing it dynamically. As such, you may be better off simply making individually-named constants such as XL, YL, ZL.