2
\$\begingroup\$

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
\$\endgroup\$
9
  • \$\begingroup\$ I am not familiar with GLSL: What is the reason to pass an integer as float to the function? \$\endgroup\$ Commented Aug 11, 2019 at 17:35
  • \$\begingroup\$ GLSL 1.2 does not support integers properly(only simulates them with floats) so using a float makes no difference and is more explicit. \$\endgroup\$ Commented Aug 11, 2019 at 19:52
  • \$\begingroup\$ @J.H : Gotta ask this: why ist the array called lut? \$\endgroup\$ Commented Aug 14, 2019 at 13:58
  • 2
    \$\begingroup\$ @GregorOphey It's short for LookUp Table, I presume. \$\endgroup\$ Commented Aug 15, 2019 at 11:17
  • 2
    \$\begingroup\$ These types are standard GLSL types. GLSL does not support #includes. They are defined by the language. They're pretty straight forward, though. vec4 = union { struct { float x; float y; float z; float w; }; struct { float r; float g; float b; float a; }; float [4] }; \$\endgroup\$ Commented Aug 21, 2019 at 1:48

1 Answer 1

3
\$\begingroup\$

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 << 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.
\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.