Converting 8 bit color into RGB value
Asked Answered
B

2

7

I'm implementing global illumination in my game engine with "reflective shadow maps". RSM has i.a. color texture. To save memory. I'm packing 24 bit value into 8 bit value. Ok. I know how to pack it. But how do I unpack it? I had idea to create a 1D texture with 8 bit palette, with 255 different colors. My 8 bit color would be index of pixel in that texture. I'm not sure how to generate this kind of texture. Are there any mathematical ways to convert 8 bit value into rgb?

@edit The color is in this format:
RRR GGG BB

@edit2: And I'm packing my colour like this:

int packed = (red / 32 << 5) + (green / 32 << 2) + (blue / 64);
//the int is actually a byte, c# compiler is bitching if it's byte.

@edit3:
Alright, I found a way to do this I think. Tell me if it's wrong.

@edit4 It's wrong...

int r = (packed >> 5) * 32;    
int g = ((packed >> 2) << 3) * 32;    
int b = (packed << 6) * 64;
Bibcock answered 9/9, 2012 at 9:37 Comment(0)
B
8

In javascript

Encode

encodedData = (Math.floor((red / 32)) << 5) + (Math.floor((green / 32)) << 2) + Math.floor((blue / 64));

Decode

red = (encodedData >> 5) * 32;
green = ((encodedData & 28) >> 2) * 32;
blue = (encodedData & 3) * 64;

While decoding we are using AND Gate/Operator to extract desired bits and discard leading bits. With green, we would then have to shift right to discard bits at right.

While encoding Math.floor is used to truncate decimal part, if rounded off it would create total value greater than 255 making it a 9 bit number.

UPDATE 1
It does not provide accurate results if we divide color by 32 or 64.

RRRGGGBB

R/G = 3bit, max value is 111 in binary which is 7 in decimal. B = 2bit, max value is 11 in binary which is 3 in decimal.

We should divide R/G by value equal or greater than 255/7 and B by value equal or greater than 255/3. We should also note that in place of Math.floor we should use Math.round because rounding off gives more accurate results.

Buonarroti answered 12/8, 2014 at 7:15 Comment(0)
C
6

To convert 8bit [0 - 255] value into 3bit [0, 7], the 0 is not a problem, but remember 255 should be converted to 7, so the formula should be Red3 = Red8 * 7 / 255.

To convert 24bit color into 8bit,

8bit Color = (Red * 7 / 255) << 5 + (Green * 7 / 255) << 2 + (Blue * 3 / 255)

To reverse,

Red   = (Color >> 5) * 255 / 7
Green = ((Color >> 2) & 0x07) * 255 / 7
Blue  = (Color & 0x03) * 255 / 3
Canella answered 17/6, 2016 at 5:45 Comment(1)
The tradeoff here for code cleanliness is that red and green each have 3 bits for 8 slices {0, 36.4, 72.9, 109.3, 145.7, 182.1, 218.6, 255} whereas blue only has 2 bits to work with, which gives 4 slices {0, 85, 170, 255}.Printable

© 2022 - 2024 — McMap. All rights reserved.