2012-09-09 300 views
4

我正在使用“反射阴影贴图”在我的游戏引擎中实现全局照明。 RSM有i.a.颜色纹理。为了节省内存。我将24位值打包成8位值。好。我知道如何打包它。但是,我如何解开它?我有想法用8位调色板创建一维纹理,有255种不同的颜色。我的8位颜色将是该纹理中像素的索引。 我不知道如何生成这种纹理。 有没有任何数学方法将8位值转换为rgb?将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; 

回答

3

在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; 

解码时,我们使用的是与门/操作员来提取所需位并丢弃前导位。随着绿色,我们将不得不右移丢弃右边的位。

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

UPDATE 1
如果我们通过32或64

RRRGGGBB划分颜色

R/G = 3位,最大值它不提供准确的结果是二进制也就是7在111小数。 B = 2位,二进制中最大值为11,十进制为3。

我们应该用等于或大于255/7的值和等于或大于255/3的值来区分R/G。 我们还应该注意,代替Math.floor,我们应该使用Math.round,因为舍入可以提供更准确的结果。

0

要将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