Skip to content

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 中,调色板的处理流程为:

  1. 内存读取:从 Wasm 线性内存的 0x05000000(BG)和 0x05000200(OBJ)读取 512 字节的调色板数据。
  2. 颜色转换:将每个 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;
  3. 查找表缓存:预先生成 BG 和 OBJ 各 256 项的 RGBA 查找表,渲染时直接使用,避免重复计算。
  4. 透明色处理:索引 0 对应的像素跳过绘制(Alpha 设为 0),实现透明效果。

相关概念

  • Tile — 使用调色板索引存储颜色信息的 8×8 图块
  • Sprite — 使用 OBJ 调色板的精灵图形