glampert
glampert

Reputation: 4411

Porting desktop GLSL shader that uses bit operations to GLES

I'm porting a desktop OpenGL application to GLES-2 (iOS specifically). In the desktop version, some GLSL shaders relied on integer bit operations, which GLES lacks.

This function was used originally in a Fragment Shader:

int reverseByte(int a)
{
    int b = 0;
    for (int i = 0; i < 8; i++)
    {
        b <<= 1;
        b |= ((a & (1 << i)) >> i);
    }
    return b;
}

// ---- usage example: ----

// get inputs from somewhere, just some test values here...
int r = 255;
int g = 128;
int b = 20;

r = reverseByte(r);
g = reverseByte(g);
b = reverseByte(b);

/* produces:
r = 255
g = 1
b = 40
*/

// color would then be normalized to [0,1] range and further used...

It reverses the order of bits in a byte. This is used with RGB colors, in the [0,255] range. GLES lacks integer bit manipulation, so the above function doesn't compile. I did some research trying to find a replacement for it and found several other possible ways of reversing bits in here, but all rely on integer bit operations.

My question is: Is there a way to achieve similar or equivalent result using just floating point operations and/or the stuff available in GLSL-ES?

Side notes:

  1. I cannot precompute the values in the CPU and pass data as a texture or whatever, as the data is procedurally generated by the shader.

  2. You might think of suggesting that I pack the data into a texture, upload it to the CPU, process it and then update the texture with the results. Well, that is actually my current solution, but performance is very poor due to the large data transfers. I would very much like to be able to do it directly in the shader.

Upvotes: 1

Views: 867

Answers (1)

ratchet freak
ratchet freak

Reputation: 48196

it's a bit involved but this should do the trick:

int b=0;
for (int i = 0; i < 8; i++)
{
    b *= 2;
    b += mod(a, 2);
    a /= 2;
}

Upvotes: 5

Related Questions