Files
gplan-2/design/art/art-pipeline-tools.md
T

25 KiB
Raw Blame History

美术后处理与校验工具清单

性质:本文件是 tools/ 下美术资产处理与校验脚本的用法清单。回答三件事:这类资产该跑哪件工具、命令怎么敲、判据与坑在哪。 边界:只管工具用法,不立美术规格。色值、画布、体量、命名与验收条款归 art-bible(§4.1 主色板、§8 资产与技术规范)和 art-assets-checklist;命令与源码冲突时以源码现行为准,美术规格冲突时以 art-bible 为准。素材入库与代码接线归 asset-path-map,不在本文件。 分工:art-prompts 管角色级提示词与五步出图流程,camp-scene-prompts 管营地场景分层提示词与四步流程;两卡只把「后处理」一步指到本文件。提示词怎么写出图、出完图怎么处理,是两件事。 命令前提:以下命令均在仓库根执行。素材不入 git,worktree 缺件时部分脚本回退主检出 D:/code/g-plan2,部分直接返回错误,见各节「已知坑与适用边界」。

按资产类型选工具

资产类型 先跑 再跑或校验 说明
角色精灵(八敌、主角) tools/pixelize_candidates.py tools/standee_asset_check.py、tools/palette_check.py 需要收网格时加 --fixer
场景不透明全幅(营地背景层、战斗舞台背景) 无专用工具 tools/palette_check.py 只出读数 见「三条已知边界」第 3 条
场景透明分层(围墙层、八个物件层) 无专用工具 tools/palette_check.py 只出读数 现役批量处理的键表只认角色键
UI 框材(面板、按钮、石框、底噪、图标) tools/quantize_ui_skin.py tools/palette_check.py、tools/path_check.py 主题小件另跑 tools/gen_theme_icons.py
地形瓦片 tools/recolor_terrain_tiles.py tools/palette_check.py 只换色,不重绘
整屏样张 tools/render_sample_sheet_v3.py、tools/render_level_map_sheet.py tools/shot_checker.py;棋盘回归用 tools/golden_board_crop.py 加 tools/golden_compare.py 样张脚本生成后自带机检

三条已知边界

  1. pixelize_candidates.py 不能处理任意资产。 main() 写死 SIZES 角色键表,只遍历这八个键的子目录;目录名不在表里就跳过,没有单文件入口,也没有通用目录模式。
  2. palette_check.py 不做色相禁入带检查,也没有全图明度带检查。 它只统计单张色数,以及对基线判新增色近色;HSV 300°–345° 禁入带与 §4.1 的明度带不在它的检查范围。
  3. 现存工具链没有「不透明全幅背景件」的专用入口。 角色批量处理按角色键,UI 量化按键名,瓦片换色按 terrain_*_dungeon 命名,整屏样张是合成器;没有一件接受一张不透明全幅场景图并输出同尺寸成品。camp-scene-prompts.md 第 3 步写明背景层不去底,但这一步没有对应的仓库命令。

tools/pixelize_candidates.py

一句话定位:把远程生图的角色候选批量处理成透明底像素精灵;带 --standee48 时按逐键档高产出站桩源档。

归属:仓库内 tools/pixelize_candidates.py。

输入与输出:默认批量模式读 <批次根>/<角色键>/v*.png,角色键取 SIZES 的八个键;输出 <角色键>/pixel-<n>.png、四联底测试条 pixel-<n>-strip.png,批次根再出一张 0-像素化预览.png。站桩模式读 <批次根>/<角色键>/pixel-1.png 与 <批次根>/hero-ref/edit/normal_1x.png,有 attack_1x.png、hit_1x.png 时一并产出;输出 character_enemy_<键>.png、character_hero_portrait.png、character_hero_attack.png、character_hero_hit.png。

用法命令:

python tools/pixelize_candidates.py <候选批次目录>
python tools/pixelize_candidates.py <候选批次目录> --fixer
python tools/pixelize_candidates.py <候选批次目录> --standee48
python tools/pixelize_candidates.py <候选批次目录> --standee48 --standee-out game/assets/art/character
python tools/pixelize_candidates.py <候选批次目录> --fixer --fixer-exe D:/code/pixel-art-fixer/rust/target/release/pixelfixer.exe

判据或口径:SIZES 是中间图最长边,不是最终体量——goblin/giant_spider/hook_horror 96,bugbear/duergar 128,ogre_chief/drider/duergar_king 192。STANDEE_TIER_H 是站桩档高——goblin 36、giant_spider 38、duergar 46、hook_horror 58、bugbear 62、ogre_chief 74、drider 90、duergar_king 94;主角取 STANDEE_SLOT_H 48。站桩源宽上限 75,脚贴画布底缘。去底走奶油描边屏障法,屏障法保留面积低于底色门路径的 60% 时自动回落;随后吃描边。像素化顺序:内容裁剪、BOX 预滤到 4 倍、中位切分量化 64 色(QUANT_COLORS)、NEAREST 降到目标、alpha 二值(阈值 128)、删小于 10px 的孤立不透明域、边缘色内插 2 遍。四联底测试条的四底色在 STRIP_BGS。正常结束退出 0;源码没有显式退出码,未捕获异常按 Python 默认非零。

已知坑与适用边界:键表固定,任意资产不能直接跑,见「三条已知边界」第 1 条。候选文件名须以 v 开头且不含 pixel;命名解析只取 v 后一位数字,v10.png 会与 v1.png 落到同一个 pixel-1.png。--standee48 分支读完 pixel-1.png 后直接返回,--fixer 在站桩分支不生效;要先跑一次带 --fixer 的批量模式。--fixer 调用失败只打印一行并回退原图,批次继续,不会以非零退出码中断。去底依赖奶油描边;描边被压暗开缺口会漏灌,脚本按 60% 面积阈值回落,但仍假定底色均匀浅色。输出是角色精灵,不处理不透明全幅件。

外部工具:pixel-art-fixer

一句话定位:检测伪像素网格并把图重建为原生分辨率的真像素图;是 --fixer 的收网格后端。

归属:仓库外 D:/code/pixel-art-fixer,Retro Diffusion 开源,MIT。可执行文件 D:/code/pixel-art-fixer/rust/target/release/pixelfixer.exe;pixelize_candidates.py 的默认路径同此,可用 --fixer-exe 覆写。

输入与输出:PNG 或 JPEG,最短边不小于 16px、总像素不超过 4MP。process 输出原生 1x PNG,并在 stdout 打一行 JSON,含 cols、rows、step_x、step_y、consensus、mode 与耗时。透明按每格多数保留。

用法命令:

D:/code/pixel-art-fixer/rust/target/release/pixelfixer.exe process <输入.png> <输出.png> full
D:/code/pixel-art-fixer/rust/target/release/pixelfixer.exe process <输入.png> <输出.png> fast
D:/code/pixel-art-fixer/rust/target/release/pixelfixer.exe process <输入.png> <输出.png> full legacy
D:/code/pixel-art-fixer/rust/target/release/pixelfixer.exe recon <输入.png> <step_x> <step_y> <cols> <rows> <输出.png>
D:/code/pixel-art-fixer/rust/target/release/pixelfixer.exe full <输入.png>

判据或口径:process 做自动检测加重建,默认重建走 two_stage_pack——量化只用于决定结构,颜色取原图对应像素;加 legacy 改走旧的 mode-vote 重建。recon 是已知网格参数只做重建,默认 raw 不量化,传 palette 才启用自动色板,另可传 dark。full 与 fast 只检测不写图,逐图打 JSON;full 跑完整仲裁,fast 只跑便宜检测器。退出码:成功 0;process 输入不合法或写图失败 1;用法错误或未知命令 2。

已知坑与适用边界:输出常是几十到几百像素的原生图,显示必须 NEAREST 放大。它是收网格器,不是降噪或调色器;色数与色板仍归 palette_check.py 与 standee_asset_check.py。recon 不检测网格,参数给错就按错的网格重建。pixelize_candidates.py 只在 --fixer 时调用 process,失败打印一行后回退原图。仓库内的可执行文件是本地构建产物;换机器要按 README 的 Rust 用法执行 cargo build --release。

tools/standee_asset_check.py

一句话定位:站桩素材硬闸,逐件校验档高、宽度、底锚、色数、alpha 二值与描边亮度。

归属:仓库内 tools/standee_asset_check.py。

输入与输出:默认读 game/assets/art/character/ 下固定 11 件——八敌 character_enemy_<键>.png,主角 character_hero_portrait.png、character_hero_attack.png、character_hero_hit.png。输出 PASS/FAIL 文本,或 --json 机器可读结果。

用法命令:

python tools/standee_asset_check.py
python tools/standee_asset_check.py game/assets/art/character
python tools/standee_asset_check.py game/assets/art/character --json

判据或口径:档高逐键取自 pixelize_candidates.STANDEE_TIER_H,主角三态 48。源宽不大于 75,即乘 2 后不超站桩盒宽 150。画布底行至少一个不透明像素,即脚贴底缘。色数不大于 32,只统计 alpha>0 的唯一 RGB。alpha 只允许 0 或 255,出现中间值即判非整数倍缩放痕迹。敌人轮廓像素中暖白描边占比不低于 40%;暖白指亮度不低于 150 且饱和不高于 0.35。主角三态豁免描边断言。全过 0,任一缺失或红灯 1。

已知坑与适用边界:主角三态描边实测约 0.4% 暖白,属暗边已知缺口,本闸豁免、不判红;要验主角描边得另找证据。文件名必须与固定清单完全一致,缺一件即失败;目录里多出的 PNG 不检查。它只查站桩 11 件,不覆盖棋盘小人、场景层、UI 或瓦片。色数口径必须排除全透明像素;按所有像素计会假报 33 色。

tools/palette_check.py

一句话定位:扫目录内 PNG,报单张色数与新增色,并按基线色板判新增色近色。

归属:仓库内 tools/palette_check.py。

输入与输出:递归读目录下所有 .png;可选 --baseline 目录作为基线色板。输出逐张 PASS/WARN/FAIL、小计与累计新增色。

用法命令:

python tools/palette_check.py <待检目录>
python tools/palette_check.py <待检目录> --baseline <基线目录>

判据或口径:单张色数等于 alpha>0 的唯一 RGB 数,排除全透明。无 --baseline 时是只读模式,只出读数、不判红。有基线时,本图颜色减去基线颜色并集得到新增色;新增色与基线任一色的最大单通道差小于 8/255 即判近色红灯。48 色是设计色板 token 上限,不是单张 PNG 的色数;单张 32 色冻结由 standee_asset_check.py 执法,本工具的单张色数只报读数。退出码:0 通过,1 有新增色红灯,2 没给目录。

已知坑与适用边界:近色只判新增色对基线,不做存量色两两互查。不做色相禁入带检查,也没有全图明度带检查,见「三条已知边界」第 2 条。单张色数超过 32 只标 WARN 或读数,不进退出码;文件头写的「超单张上限判红」与现行源码不一致,按源码为准。文件头提到 --tokens,但现行 main() 没有这个参数分支,TOKEN_MAX=48 目前只是常量。基线目录不存在时不会返回错误:基线色集为空,新增色判据失效。只排除 alpha=0 的像素,半透明像素的 RGB 也计入色数。

tools/quantize_ui_skin.py

一句话定位:把 UI 复用包里的面板、按钮、石框、底噪与图标按 token 明度带量化改色,产出 game/assets/art/ui/ 下的终稿件。

归属:仓库内 tools/quantize_ui_skin.py。

输入与输出:源包固定为 artwork/ui-reuse-2026-09-23/ 下的 Kenney 与 OGA CC0 件;当前仓缺位时回退主检出 D:/code/g-plan2。输出 14 件到 game/assets/art/ui/——5 件框材与底噪、4 枚营地图标、5 枚节点图标。

用法命令:

python tools/quantize_ui_skin.py

判据或口径:面板、按钮、石框与底噪按五条硬编码 ramp 做明度重映射,保留 alpha 与纹理结构;ramp 常量在脚本顶部 RAMP_*。图标走单色重着色:钥石取奖励金,柜台四件取暖白;节点五件取暖白并烘到 20×20。节点图标自检三项——全像素只能是 NODE_WARM 或透明、尺寸 20×20、两两 alpha 剪影错位率不低于 0.08;失败 SystemExit(1)。复用闸四道(量化、禁入带、灰度可辨、CC0 授权)的来源说明在文件头;脚本实际自检只跑节点图标这三项,框材件没有逐件断言。全过 0,失败 1,源件缺位抛 FileNotFoundError。

已知坑与适用边界:源包路径、子目录名与文件名全部硬编码;换包或改名直接 FileNotFoundError,不是通用量化器。源包在 artwork/,整目录不入 git;worktree 或新检出缺件时才会回退主检出,主检出也没有就失败。只服务这一批 UI 复用件,不处理角色、场景或瓦片。输出覆盖同名件;改色值要改脚本顶部 ramp 常量后重跑,再让 Godot 重导入。

tools/recolor_terrain_tiles.py

一句话定位:把 dungeon 地形瓦片按家族与亮度秩序换色,产出 underdark 与 deep_underdark 两套。

归属:仓库内 tools/recolor_terrain_tiles.py。

输入与输出:默认源与输出都是 game/assets/art/board/;只匹配 terrain_*_dungeon.png 与 terrain_*_dungeon_<数字>.png。输出把文件名里的 _dungeon 换成 _underdark 或 _deep_underdark。

用法命令:

python tools/recolor_terrain_tiles.py
python tools/recolor_terrain_tiles.py --palettes underdark
python tools/recolor_terrain_tiles.py --src <源目录> --out <输出目录> --palettes underdark,deep_underdark

判据或口径:源图每个唯一色先按 RGB 距离归到 dungeon 锚槽的四家族——墙顶、立面、地面、雷坑;再在家族内按亮度秩序线性映射到目标色表同家族槽列。目标色表 PALETTES 硬编码在脚本里,槽值来源为归档包 archive/归档-terrain-walls-2026-09-26.zip 内的生成器。映射确定性,无随机;脚本打印每枚源图的唯一色数。成功 0;源目录没有匹配瓦片时打印「零输出」并返回 1。

已知坑与适用边界:只做换色,不重绘、不增删结构;结构件缺件不能用它补。家族归属靠最近锚色距离,偏离锚槽的颜色可能归错家族。只认 dungeon 命名,其他图类型或其他前缀不处理。默认输出覆盖同目录同名件;源瓦片不入 git,跑前确认盘上源件在。

tools/gen_theme_icons.py

一句话定位:程序化生成 UI 主题小位图——滑轨柄三态、SpinBox 上下箭头、OptionButton 箭头、勾选框四态。

归属:仓库内 tools/gen_theme_icons.py。

输入与输出:无输入参数;输出 9 张 PNG 到 game/assets/art/ui/gen/。

用法命令:

python tools/gen_theme_icons.py

判据或口径:色值取 game/presentation/views/ui_kit.gd 的既有常量,脚本头注明溯源;不新增美术素材、不改 art-bible §7。脚本幂等,重复执行覆盖同名件。滚动条柄不走位图,由 StyleBoxFlat 承载,本脚本不产出。无显式退出码;正常结束 0,写入异常按 Python 默认非零。

已知坑与适用边界:脚本没有验收断言,生成完要目检并让 Godot 重导入。改色值只能改脚本顶部常量再重跑,脚本不读 ui_kit.gd 的运行时值。只出主题小件,不处理面板、图标或场景。产出在素材目录,不入 git。

tools/shot_checker.py

一句话定位:整屏截图机检,判屏级骨架、文字对比、背景纹理、明度三档带与文字是否还在框内。

归属:仓库内 tools/shot_checker.py。

输入与输出:截图目录,默认屏清单 shot_menu.png、shot_camp.png、shot_level.png、shot_battle.png;同目录 shot_meta.json 提供取样框。输出逐项 PASS/FAIL 摘要。

用法命令:

python tools/shot_checker.py <截图目录>
python tools/shot_checker.py <截图目录> shot_menu.png shot_battle.png

判据或口径:A 屏级骨架——PNG 存在、任一边 1280、灰度 std 不低于 8(取值在圣经 §7.2 文字 4.5:1 推论下界之下、正常实测最低 19.3 之上)、唯一色数不低于 40(正常实测地板 60 的 2/3,低于一切正常屏;色数异常回落=画面异常信号)。B 文字对比——战斗 C 区面板与明细带提示的 WCAG 不低于 4.5:1。C 明度三档——战斗屏信息面高于世界中,世界中高于世界底。D 文字禁压纹理——文字框背景中带灰度 std 不高于 18。F 文字在——菜单标题框内与中位灰度差大于 60 的像素占比落在 2% 到 55%。B/C/D 只在清单含 shot_battle.png 时跑,F 只在含 shot_menu.png 时跑,其余屏只跑 A。全过 0,缺参数或任一失败 1。

已知坑与适用边界:截图必须由窗口化 shot_probe 产出;headless 没有渲染面,截图是空的。shot_meta.json 缺失时 B/C/D 直接判 meta 几何缺失,不会跳过。尺寸断言按「任一边等于 1280」放行;1920×1080 截图两边都不等于 1280,会被判非工程档,与文件头「1920 档 1.5×」说明不一致,按源码为准。焦点预算是目检项,机检不判。

tools/golden_board_crop.py

一句话定位:按 board_shot_probe 输出的 board_meta.json 从整屏截图裁出棋盘区,供 golden 逐像素比对。

归属:仓库内 tools/golden_board_crop.py。

输入与输出:三个参数依次是 board_meta.json、截图目录、输出目录;读截图目录内 board_<tag>.png,按 meta 矩形裁剪,写输出目录同名文件。

用法命令:

python tools/golden_board_crop.py <board_meta.json> <截图目录> <输出目录>

判据或口径:meta 键即 tag,矩形字段为 x/y/w/h;越界按图像边界收拢。meta 缺失、空表、截图缺失、矩形字段非法或退化,均返回 1;全部裁出 0。禁硬编码像素:布局改动只重跑探针刷新 meta。

已知坑与适用边界:依赖 board_shot_probe 的 meta 与截图命名;手工截图或改名不认。只裁剪不缩放,输出尺寸随 meta 矩形。它不跑比对;比对是 golden_compare.py。

tools/golden_compare.py

一句话定位:黄金图与实测截图逐屏灰度对比,报视觉回归。

归属:仓库内 tools/golden_compare.py。

输入与输出:黄金图目录、新截图目录、可选屏清单;默认四屏 shot_menu.png、shot_camp.png、shot_level.png、shot_battle.png。输出逐屏 changed 占比与 PASS/FAIL。

用法命令:

python tools/golden_compare.py game/tests/golden <截图目录>
python tools/golden_compare.py game/tests/golden <棋盘裁剪目录> board_L1_dungeon.png board_L2_underdark.png board_L3_deep_underdark.png

判据或口径:两图尺寸必须一致;逐像素灰度差大于 16 记为 changed。changed 占比超过 2% 判失败;尺寸不符、缺基线或缺截图也判失败。全过 0,有失败 1。

已知坑与适用边界:只比灰度,不比色相;纯换色但明度相同可能漏过。基线在 game/tests/golden/,资产换代要显式重制并按该目录 README 记录判定,不能拿重制基线掩盖回归。默认四屏不含棋盘与关卡图;比棋盘要传裁剪后的文件名,比关卡图要传 level_map.png。截图分辨率必须与基线一致,基线是 1280 档。

tools/render_sample_sheet_v3.py

一句话定位:战斗一屏样张的当前生成器,出 1280×800 与 1920×1080 两版,并在生成过程中跑断言。

归属:仓库内 tools/render_sample_sheet_v3.py。

输入与输出:读 game/assets/art/board 的 21 枚瓦片、game/assets/art/character 的小人与立绘、game/assets/ui/icons 的状态图标;素材缺位回退主检出。输出 artwork/mockups/sample-batch-v3-final-2026-09-30.png、sample_battle_screen_1280x800.png、sample_battle_screen_1920x1080.png;有基线时再出 sample_battle_screen_before_after.png;机检报告写到 reports/。

用法命令:

python tools/render_sample_sheet_v3.py
python tools/render_sample_sheet_v3.py --save-baseline
python tools/render_sample_sheet_v3.py --gen-assets

判据或口径:生成即验。F 段管方案甲拼装、旗位、脚锚、0 格字形、微光带限、立面双明度带、悬崖同源;A 段管色板对表、禁入带、周界闭合、明度对比、混排、净空、观感密度;整屏扩展含 S1–S4、P1–P5、V1、V10、A5b。全绿 0,有红 1,报告逐项列 PASS/FAIL。分区几何不设脚本常量:B 区高 / C 区宽 / AP 条高 / 明细带两态高经 tools/layout_config.py 读 game/data/tables/battle_layout.tres,与游戏侧 ConfigDb.presentation.battle_layout 同源。--gen-assets 产四件——scene_stage_plaza.png 48×12 与 ui_armor_light、ui_armor_ward、ui_armor_heavy 三枚 24×24;尺寸或色数不过直接 RuntimeError。--save-baseline 只把当前整屏存成基线并返回 0,整屏断言不跑,板面断言即使有红也不改退出码。

已知坑与适用边界:固定输出文件名带 2026-09-30,重跑覆盖同名件。字体硬编码 C:\Windows\Fonts\msyh.ttc,非 Windows 环境起不来。第一次跑要先 --save-baseline,否则 V10 因缺基线判红。素材不入 git;worktree 缺件会抛 FileNotFoundError,回退主检出后仍缺也失败。它产的是样张与机检报告,不是游戏内资产;唯一例外是 --gen-assets 的四件。

tools/render_level_map_sheet.py

一句话定位:关卡画面样张生成器,出岔路、入口、单链与换层示意,并跑断言。

归属:仓库内 tools/render_level_map_sheet.py。

输入与输出:读 artwork/ui-reuse-2026-09-23/ 的节点图标与字体、game/assets/art/ui/backdrop_stone.png;画布公式、停点标题与 HIT_PAD 从 game/presentation/views/level_map_screen.gd 解析。输出 artwork/mockups/level-map-sheet-v1-2026-09-28.png;机检报告写到 reports/。

用法命令:

python tools/render_level_map_sheet.py

判据或口径:断言 L1 图标互辨、L2 四态与 Boss 环灰度、L3 对比不低于 4.5:1、L4 禁入带零命中、L5 画布自适应、L6 独立屏底、L7 占位区不侵入;另有 SRC 同源、ST 态齐备、S3 换层。全绿 0,有红 1,报告逐项列 PASS/FAIL。节点图标 20px、通道线宽 2/3/4px 等冻结值在脚本顶部;画布公式不自立,解析自 level_map_screen.gd。

已知坑与适用边界:依赖 level_map_screen.gd 存在且常量写法可解析;改常量写法会让脚本抛 FileNotFoundError 或解析失败。字体同样硬编码 Windows 字体。固定输出文件名带 2026-09-28,重跑覆盖。样张是验收图,不是游戏资产。

tools/render_sample_sheet.py

一句话定位:战斗一屏样张 v2 生成器,现行 v3 的前一版。

归属:仓库内 tools/render_sample_sheet.py。

输入与输出:读同一批游戏素材,输出 artwork/mockups/sample-batch-v2-2026-09-28.png;机检报告写到 reports/。

用法命令:

python tools/render_sample_sheet.py

判据或口径:断言 F1–F7 与 A1–A6;全绿 0,有红 1。产物为 1280×800 单版,没有 v3 的 1920 档、整屏 S/P 段与改前改后并排。

已知坑与适用边界:已被 render_sample_sheet_v3.py 取代,只用于复现 v2 旧口径,不要拿它出新冻结。固定输出名与报告名带 2026-09-28,重跑覆盖。字体与素材依赖同 v3。

tools/path_check.py

一句话定位:扫描 asset-path-map.md 声明的目录与现役文件,以及代码里的 res://assets/art 引用,报悬空与退役命名。

归属:仓库内 tools/path_check.py。

输入与输出:可选 --repo 仓库根、--code 代码根,默认 . 与 game。输出 L1 目录、L2 文件、L3 代码引用三段 PASS/FAIL。

用法命令:

python tools/path_check.py
python tools/path_check.py --repo . --code game

判据或口径:L1 查 asset-path-map §1 的声明目录,design/art/candidates 按需创建豁免。L2 查 game/assets/art 的四个语义子目录与现役文件清单,含主角 idle/walk/portrait、八敌、铲三帧、封印印记。L3 grep 代码里的 res://assets/art 引用,核对盘上存在性,并检出 board_floor、board_wall、pillar_dungeon、production/mockups 等退役命名;路径模板含 %s 或 %d 的跳过。worktree 素材未同步时,缺失项标 SKIP 不判红;主区完整素材环境才全量判。全过 0,有红灯 1。

已知坑与适用边界:依赖 asset-path-map.md 的声明清单与代码常量;新增素材目录不更新文档就不会被查。素材不入 git,worktree 空或半同步会大量 SKIP,不能据此判断主区健康。只核对路径存在与退役命名,不核对图像内容、尺寸或色板。