Appearance
Palette(调色板)
是什么
Palette(调色板)是 GBA 图形系统中的颜色查找表。GBA 使用 BGR555 格式的 15 位颜色编码,每个颜色通道占 5 位(共 32768 种颜色)。调色板将图块(Tile)中存储的颜色索引值映射为实际的颜色值。
GBA 有两组独立的调色板:
- BG 调色板:256 色,地址
0x05000000(512 字节)。 - OBJ 调色板:256 色,地址
0x05000200(512 字节)。
为什么需要
调色板机制是 GBA 在有限显存条件下实现丰富色彩的关键设计:
- 节省显存:图块数据存储的是颜色索引而非完整颜色值,4bpp 模式下每个像素仅占 4 位。
- 颜色动画:通过修改调色板可以实现颜色渐变、闪烁等效果,而无需修改图块数据。
- 多彩复用:不同的调色板组(16 色模式下有 16 组)可以让相同的图块呈现不同的颜色。
在 pokeemerald-wasm 项目中,需要将 GBA 的 BGR555 颜色转换为 Canvas 支持的 RGBA8888 格式。
原理与实现
BGR555 颜色格式
GBA 的每个颜色用 16 位表示,格式如下:
bit 15: 未使用(必须为 0)
bit 14-10: Red(红色,5 位,0-31)
bit 9-5: Green(绿色,5 位,0-31)
bit 4-0: Blue(蓝色,5 位,0-31)5 位色阶(0-31)转换为 8 位色阶(0-255)的公式:
8bit_Value = (5bit_Value * 255 + 15) / 31或使用近似公式(速度快,但略有误差):
8bit_Value = (5bit_Value << 3) | (5bit_Value >> 2)调色板内存布局
在 16 色模式(4bpp)下:
- BG 调色板:分为 16 组,每组 16 色。图块通过映射表中的调色板组号选择使用哪组。
- OBJ 调色板:同样分为 16 组。OAM 的 ATTR2 中 bit 12-15 指定调色板组号。
在 256 色模式(8bpp)下:
- 整个 256 色调色板作为一个整体使用,图块的 8 位索引直接映射到调色板的 0-255 项。
特殊颜色
索引 0 在 BG 调色板中代表透明色(不会绘制任何像素),但在 OBJ 调色板中,索引 0 也是透明色——精灵中索引为 0 的像素不会被绘制。
在 pokeemerald-wasm 中的实现
在 pokeemerald-wasm 中,调色板的处理流程为:
- 内存读取:从 Wasm 线性内存的
0x05000000(BG)和0x05000200(OBJ)读取 512 字节的调色板数据。 - 颜色转换:将每个 16 位 BGR555 颜色值转换为 32 位 RGBA8888 格式:javascript
const r5 = (color >> 10) & 0x1F; const g5 = (color >> 5) & 0x1F; const b5 = color & 0x1F; const r8 = (r5 * 255 + 15) / 31; const g8 = (g5 * 255 + 15) / 31; const b8 = (b5 * 255 + 15) / 31; - 查找表缓存:预先生成 BG 和 OBJ 各 256 项的 RGBA 查找表,渲染时直接使用,避免重复计算。
- 透明色处理:索引 0 对应的像素跳过绘制(Alpha 设为 0),实现透明效果。