将8位色彩转换为RGB值

7
我正在使用“反射阴影贴图”在我的游戏引擎中实现全局光照。RSM具有颜色纹理。为了节省内存,我将24位值打包成8位值。好的,我知道如何打包它。但是如何解包呢?我想创建一个带有8位调色板的1D纹理,其中包含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个回答

8

在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门/运算符来提取所需位并丢弃前导位。对于绿色,我们需要向右移动以丢弃右侧的位。
在编码时,使用Math.floor截断小数部分,如果四舍五入,则会创建总值大于255的9位数字。
更新1 如果我们将颜色除以32或64,则无法提供准确的结果。
RRRGGGBB
R/G = 3位,最大值为二进制中的111,即十进制中的7。 B = 2位,最大值为二进制中的11,即十进制中的3。
我们应该将R/G除以等于或大于255/7的值,将B除以等于或大于255/3的值。 我们还应注意,在Math.floor的位置上,我们应该使用Math.round,因为四舍五入可以得到更准确的结果。

5

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

将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

在代码清晰性方面的权衡是,红色和绿色分别有3位用于8个切片{0、36.4、72.9、109.3、145.7、182.1、218.6、255},而蓝色只有2位可以使用,这仅提供了4个切片{0、85、170、255}。 - Samuel Clay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接