将8位颜色转换为RGB值

时间:2012-09-09 09:37:45

标签: colors bit-manipulation rgb 8-bit

我正在使用“反射阴影贴图”在我的游戏引擎中实现全局照明。 RSM有i.a.颜色纹理。为了节省内存。我将24位值打包成8位值。好。我知道怎么收拾它。但是我该如何打开包装呢?我有意创建一个带有8位调色板的一维纹理,有255种不同的颜色。我的8位颜色将是该纹理中的像素索引。 我不知道如何生成这种纹理。 有没有数学方法可以将8位值转换为rgb?

@edit 颜色采用以下格式:
RRR GGG BB

@ EDIT2: 我正在打包我的颜色:

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:
好吧,我觉得我找到了一种方法。告诉我,如果这是错的。

@ edit4这是错误的......

int r = (packed >> 5) * 32;    
int g = ((packed >> 2) << 3) * 32;    
int b = (packed << 6) * 64;

2 个答案:

答案 0 :(得分:5)

在javascript中

编码

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

解码

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

在解码时,我们使用AND Gate / Operator来提取所需的位并丢弃前导位。使用绿色,我们必须向右移动以丢弃右边的位。

虽然编码Math.floor用于截断小数部分,但如果四舍五入,则会创建大于255的总值,使其成为9位数。

更新1
如果我们将颜色除以32或64,则不能提供准确的结果。

RRRGGGBB

R / G = 3bit,二进制最大值为111,十进制为7。 B = 2bit,最大值是二进制11,十进制为3。

我们应该将R / G除以等于或大于255/7的值,将B除以等于或大于255/3的值。 我们还应该注意,代替Math.floor,我们应该使用Math.round,因为舍入可以得到更准确的结果。

答案 1 :(得分:2)

要将8位[0 - 255]值转换为3位[0,7],0不是问题,但记住255应转换为7,因此公式应为Red3 = Red8 * 7/255。 / p>

将24位颜色转换为8位,

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

要反转,

Red   = (Color >> 5) * 255 / 7
Green = ((Color >> 2) & 0x07) * 255 / 7
Blue  = (Color & 0x03) * 255 / 3