7

我正在使用“反射阴影贴图”在我的游戏引擎中实现全局照明。RSM 具有 ia 颜色纹理。为了节省内存。我将 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;
4

2 回答 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 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.round 代替 Math.floor,因为四舍五入可以提供更准确的结果。

于 2014-08-12T07:15:13.247 回答
4

要将 8bit [0 - 255] 值转换为 3bit [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
于 2016-06-17T05:45:52.793 回答