Pio*_*iec 6 rgb bit-manipulation colors 8-bit
我正在使用"反射阴影贴图"在我的游戏引擎中实现全局照明.RSM具有颜色纹理.为了节省内存.我将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.
Run Code Online (Sandbox Code Playgroud)
@ edit3:
好吧,我觉得我找到了一种方法.告诉我,如果这是错的.
@ edit4这是错的......
int r = (packed >> 5) * 32;
int g = ((packed >> 2) << 3) * 32;
int b = (packed << 6) * 64;
Run Code Online (Sandbox Code Playgroud)
要将 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)
Run Code Online (Sandbox Code Playgroud)
扭转,
Red = (Color >> 5) * 255 / 7
Green = ((Color >> 2) & 0x07) * 255 / 7
Blue = (Color & 0x03) * 255 / 3
Run Code Online (Sandbox Code Playgroud)
在javascript中
编码
encodedData = (Math.floor((red / 32)) << 5) + (Math.floor((green / 32)) << 2) + Math.floor((blue / 64));
Run Code Online (Sandbox Code Playgroud)
解码
red = (encodedData >> 5) * 32;
green = ((encodedData & 28) >> 2) * 32;
blue = (encodedData & 3) * 64;
Run Code Online (Sandbox Code Playgroud)
在解码时,我们使用AND Gate/Operator来提取所需的位并丢弃前导位.使用绿色,我们必须向右移动以丢弃右边的位.
虽然编码Math.floor用于截断小数部分,但如果四舍五入,则会创建大于255的总值,使其成为9位数.
更新1
如果我们将颜色除以32或64,则不能提供准确的结果.
RRRGGGBB
R/G = 3bit,二进制最大值为111,十进制为7.B = 2位,最大值为二进制11,十进制为3.
我们应该将R/G除以等于或大于255/7的值,将B除以等于或大于255/3的值.我们还应该注意,代替Math.floor我们应该使用Math.round,因为四舍五入可以得到更准确的结果.