compress 2 bytes into 1 byte

Hello! I had an idea earlier today, don’t worry about what it’s for; just a test I want to do for my game :slight_smile: I already got the “dont do this” from TheAgentD :stuck_out_tongue:

When reading texture data from 2 files, I only use the red channel, and I want to compress the red values of both textures into 1 byte (2 bytes --> 1 byte).

I tried:

byte b1 = (byte) 200;
byte b2 = (byte) 255;

int i = ((b1 << 8) | (b2 & 0xFF));
System.out.println(i);

int val1 = i >> 8 & 0xFF;
int val2 = i & 0xFF;
System.out.println("b1: " + val1);
System.out.println("b2: " + val2);

Which… well… works, but not exactly, as the variable i is an integer, not a byte.

I know there will be some precision loss by doing this, but it’s for texture data that doesn’t need to be 100% accurate, just close.

How do I do this properly? and how would I extract the two bytes back out.

The only other thing I’ve thought of, is have one texture limited to 0, 1, or 2; and have the other limited to 0 to 55.

I was thinking about it the wrong way.

If I limit both of the values from 0-255 to 0-15, I can easily pack them :slight_smile:

Result:

I packed the specular texture and gloss texture into the alpha channel of the normalmap :slight_smile:
Reduces texture swaps by half! :smiley:

If you read from two textures only the red component I’d say the best optimization is to merge the two of them in one using red and green.

In general GPUs likes 16/32b chunck… everything in between will be padded…

Anyway as usually, profile :wink:

That was my first thought too, but that would still have an extra state-change on the GPU. Since there would be three textures to bind when drawing a material, instead of 2.

Since the math to get the values back (on the GPU) is super simple, it unrolls quite nicely.

[edit]
Just did a small test in my engine. I drew the model above 16 * 16 times. Using the compression thing I get 185 fps. If I send in 3 textures then I get 160 fps, and if I send in 4 then I get 150 fps.