这是《游戏美术与技术美术》三卷本的第三卷。卷一《美术制作与视觉规范》回答「美术做出来的东西,凭什么说它『对』」——定 token、定预算、定命名、定评审。卷二《技术美术与管线工程》回答「这些规范怎么接进生产」——每一道闸门谁来挡、挡什么。卷三回答的是再下一句:同一份规范,换一套风格参数还成立吗。它把「像素风」「低多边形」「卡通渲染」「暗黑」「清新」「复古赛博」这些平时只能靠形容词沟通的词,落成可测的维度、可算的距离、可跑的校验器,最后用 6 个主题包把同一份
config/visual_spec.json实例化六遍,跑同一套仿真与校验器,6 次全过,并给出 6×6 风格距离矩阵证明「同源但可区分」。
卷三的 16 章分成四块:可测风格与二维风格(第 1–3 章),三维与渲染风格(第 4–8 章),主题化与品类(第 9–14 章),装配与收官(第 15–16 章)。贯穿全书的仍是虚构的等距经营游戏 《星屑旅店》(stardust-inn)与工具链 prism(config/ + sim/ Python + core/ TypeScript + web/ 单文件 HTML),与卷一、卷二共用同一份 config/visual_spec.json 与同一组 6 个主题包(config/sp16_themes.json)。
这套书与站内既有内容的分工
站内已经有大量相邻内容,写清楚分工比重复写一遍更有价值。下面七处边界是本卷最容易混淆的,务必分清:
- 《游戏美术与技术美术》卷一《美术制作与视觉规范》 是本卷的上游。卷一管「一份规范该定哪些值」,本卷管「同一份规范在不同风格下还成不成立」。凡是「这个 token 该定多少」翻卷一,凡是「换成像素风/暗黑风之后这套还对不对」看本卷。
- 《游戏美术与技术美术》卷二《技术美术与管线工程》 管「规范怎么接进管线」。本卷不重复管线与门禁,只把卷二那条管线换 6 套风格参数各跑一遍(第 15 章)。
- 独立游戏像素美术风格指南 (约 740 行)讲的是 Aseprite 技法与素材资源——怎么画、用哪些工具、去哪找参考。本卷第 2 章首段显式划界:它讲技法,本卷讲像素调色板量化与 tile 预算的可跑账。本卷不重写它的技法。
graphics/渲染原理专题(45 篇)是原理的家:色彩管理、光照模型、后处理、纹理压缩。本卷第 5.3 与第 6 章整节做划界并外链,其余各章只做风格参数与账,不重推原理。- 《游戏引擎实现原理》卷二《渲染引擎》 是引擎实现的家(56 篇)。卡通渲染的真实管线、PBR 的着色器实现、体素到网格的转换实现都在那边,本卷只写美术侧的规范与约束。
- 游戏美术风格规范:Style Bible 怎么写才真的有用 与 移动端与 PC 性能预算管理 是口号式提纲与预算短文。本卷把「风格该有哪些维度」落成可算的风格向量与距离矩阵,把「性能预算」落成每种风格各自的整数账。
- 数据可视化无障碍色彩 与 色彩管理与 HDR 管线 讲的是图表口径与渲染管线口径。本卷取游戏美术调色板视角:同一套 WCAG 对比度与 OKLab 距离,用在不同风格的调色板上。
一句话:本卷做的是「同一份规范在不同风格下还站不站得住」,不是「怎么把画面画漂亮」。
明确不在本卷范围内
为了让边界清楚,下面这些这一卷不讲:
- 渲染原理与着色器实现(光照模型、后处理、色彩管理)——站内 graphics 专题 与《渲染引擎》卷 已覆盖。
- 资产管线与门禁规则引擎的搭建(导入校验、依赖图环检测、清单与门禁分级)——见卷二 。
- 真实 DCC 操作与真实渲染(Blender / Maya / 3ds Max / Substance / ZBrush):本机一个都没有,也不打算安装,一律标 X。
- 真实画师的审美判断(笔触质量、画质高低、二次元的「像不像」):一律标 X,需真实环境与真实画师,命令行不可复现;第 3.3、5.3、7.3、10.3 四节整节做这件事的划界。
- 具体引擎的 API 教程(Cocos / Defold / Unity 各有专书)。
- 任何第三方美术素材(本卷所有 PNG 由 PIL 程序化生成,贯穿案例为虚构游戏)。
可运行性口径
本卷每节的代码块头部注释里都写着它属于哪一档。所有代码块都在本机实跑过,正文数字等于实跑输出;但「整卷项目复现」(把全部配置与共享模块组装起来一次性跑通)尚未完成,故本页不声称整卷可复现。
| 层 | 含义 | 怎么验证 |
|---|---|---|
| S 仿真层 | Python 数值仿真:调色板量化、对比度与 OKLab 距离、面数与顶点预算、体素账、等距整数变换、通道打包字节账、风格距离矩阵 | /opt/homebrew/bin/python3 sim/st<章号>_*.py,产出 JSON + CSV + SVG + PIL 生成的 PNG |
| P 内核层 | TypeScript 配置驱动校验器:风格向量与距离、调色板断言、tile 与面数预算、命名与引用 lint、跨语言摘要对照 | node --test 'core/test/st<章号>_*.test.ts'(必须写全 glob;node --test <目录> 不发现 .ts) |
| W 网页层 | 单文件 HTML 原型:等距 tile 板、主题切换器、调色板与色盲对照画布 | node web/build_st<章号>_*.mjs 产出 HTML,再用 NODE_PATH=/opt/homebrew/lib/node_modules node web/verify_st<章号>_*.mjs 无头断言 |
| D 静态层 | 风格参数表、命名与线宽 schema、笔刷与色域 schema、比例与面部参数表、验收清单 | 仅 schema / lint 校验,且必须能被 sim/ 与 core/ 同时读入 |
| X 不可复现 | 真实画质与笔触、真实渲染、真实 DCC、真实画师审美 | 正文每处显式标注「需真实环境,命令行不可复现」 |
| B 基准 | 跨语言色彩容差、风格距离阈值敏感性、主题切换后的预算漂移 | 产出 JSON,软告警不硬失败,数字来自本机实跑 |
本卷的核心主张是**「一份规范跨风格成立」:同一份 config/visual_spec.json(卷一落盘,本卷只读)被 ① S 层 Python 仿真、② P 层 TS 校验器、③ W 层浏览器看板三处消费;第 15 章再把 naming / budget / tokens 结构实例化 6 次**(pixel / lowpoly / handdrawn / voxel / retro-cyber / cozy-clean),跑同一套仿真与校验器,6 次全过,并给出 6×6 风格距离矩阵证明「同源但可区分」。
三条跨语言纪律(与卷一、卷二、既有书稿并列):
- 预算与阈值一律整数:像素数、面数、顶点数、体素数、字节、千分比、对比度×10、风格距离×10、细节密度百分比。除法整数地板除,禁浮点 → 逐位一致。
- 色彩真源 = sRGB 8-bit 整数三元组(
[r,g,b]0–255,hex 只是显示形态)。感知量(linear / OKLab / ΔE / WCAG / 色盲 RGB)是派生量,跨语言按声明容差断言。正文一律不写「三处颜色完全相同」,只写「容差内一致,实测最大偏差 N」。 - 转换常数两语言同源:sRGB 阈值
0.04045 / 12.92、指数2.4 / 1.055 / 0.055;OKLab 用 Ottosson 同一组矩阵常数;色盲用同一组 Brettel / Viénot 矩阵。禁一侧用库、一侧手写(本机也没有colour库,天然只能同源手写)。
同样适用两条纪律:不假装能真渲染、真画——真实 DCC、真实渲染、真实画师审美一律标 X 或显式声明为示例参数;仿真数字只作同机相对量级,S 层应记录环境与输入后复现,禁止写成「提升 N 倍」这类断言。
卷三结构总览(16 章)
| 章 | 主题 | 可运行性层级 |
|---|---|---|
| 1 | 风格谱系总览与可度量维度 | S + P |
| 2 | 像素风 | S + P |
| 3 | 2D 手绘与矢量 | S + P + X |
| 4 | 低多边形 Low-poly | S + P |
| 5 | NPR / 卡通渲染 | S + P + D + X |
| 6 | 写实 PBR | S + P + X |
| 7 | 风格化厚涂 / 手绘贴图 | D + P + X |
| 8 | 体素 Voxel | S + P |
| 9 | 等距 / 2.5D | S + P + W |
| 10 | 二次元 / 日式 | D + P + X |
| 11 | 暗黑 / 恐怖 | S + P |
| 12 | 清新 / 治愈 | S + P |
| 13 | 复古 / 赛博 | S + P + W |
| 14 | 品类美术差异(休闲 / 中度 / 重度 / 独立) | S + D |
| 15 | 风格迁移与统一(同一规范跨 6 主题) | S + P + B |
| 16 | 装配:跨风格视觉规范验收 | S + P + W + B |
全书目录
前置
| 篇目 | 核心内容 |
|---|---|
| 目录 | 本页:定位、七处分工、可运行性口径与全书结构 |
| 附录 A:风格参数表、量化规则与数据集索引 | prism/ 全部文件索引、st<章号>_ 命名约定与六层复现命令 |
第一部分:可测风格与二维风格(第 1–3 章)——从「风格能不能被量化」开始,落到两种最典型的二维风格。
第 1 章 风格谱系总览与可度量维度
- 三个可测维度:色彩 / 形状 / 细节 :风格的可测化起点(S+P)
- 风格向量与风格距离矩阵 :风格向量与两两距离(S+P)
- 风格选择与项目约束 :风格与项目约束的权衡(S+P)
第 2 章 像素风
- 分辨率、像素密度与调色板上限 :分辨率与调色板上限(S+P)
- 调色板量化与抗锯齿替代 :量化误差与替代方案(S+P)
- 像素 tile 与 tile 预算 :tile 与预算(S+P)
第 3 章 2D 手绘与矢量
- 扁平色块与线宽规范 :色块与线宽规范(S+P)
- 手绘资产的切分与复用 :切分与复用(S+P)
- X:画质与笔触 :画质与笔触(X)
第二部分:三维与渲染风格(第 4–8 章)——低多边形、卡通渲染、写实、厚涂与体素五种三维取向。
第 4 章 低多边形 Low-poly
- 面数与顶点预算 :面数与顶点预算(S+P)
- 平面着色与色块划分 :平面着色与色块(S+P)
- 低多边形的引擎接入约束 :引擎接入约束(S+P)
第 5 章 NPR / 卡通渲染
第 6 章 写实 PBR
第 7 章 风格化厚涂 / 手绘贴图
- 笔刷与色域参数规范 :笔刷与色域 schema(D+P)
- 手绘贴图的分层与复用 :分层与复用清单(D+P)
- X:笔触质量 :笔触质量(X)
第 8 章 体素 Voxel
- 体素网格与体素账 :体素网格与账(S+P)
- 体素调色板与光照简化 :调色板与光照简化(S+P)
- 体素的引擎接入 :引擎接入(S+P)
第三部分:主题化与品类(第 9–14 章)——等距 2.5D 与五种可实例化的视觉主题,再回到品类差异。
第 9 章 等距 / 2.5D
- 等距投影的整数变换 :整数变换(S+P)
- 等距 tile 与遮挡规则 :tile 与遮挡规则(S+P+W)
- 等距资产的制作约束 :制作约束(S+P)
第 10 章 二次元 / 日式
第 11 章 暗黑 / 恐怖
- 低饱和色彩分级 :低饱和分级(S+P)
- 亮度分布与对比度 :亮度与对比度(S+P)
- 视觉噪声与可读性平衡 :噪声与可读性(S+P)
第 12 章 清新 / 治愈
第 13 章 复古 / 赛博
- 霓虹调色板与色彩分级 :霓虹调色板(S+P)
- 发光与溢出规范 :发光与溢出(S+P)
- 主题切换与变体管理 :主题切换与变体(S+P+W)
第 14 章 品类美术差异(休闲 / 中度 / 重度 / 独立)
- 品类与美术预算的关系 :品类与预算(S+D)
- 品类与视觉可读性 :品类与可读性(S+D)
- 跨品类复用与移植 :跨品类复用(S+D)
第四部分:装配与收官(第 15–16 章)——6 主题同源可区分的实证,与三卷总收官。
第 15 章 风格迁移与统一(同一规范跨 6 主题)
- 规范实例化:6 主题包 :6 主题实例化(S+P)
- 同源可区分:风格距离矩阵 :风格距离矩阵(S+B)
- 风格迁移的边界与代价 :迁移边界与代价(S+B)
第 16 章 装配:跨风格视觉规范验收
- 跨风格验收清单 :跨风格验收清单(S+P)
- 三卷总收官:一份规范的完整回放 :三卷总收官(S+B)
- 交付物与后续 :交付物与后续(S+P+W)
三条阅读路径
路径 A:风格谱系与二维风格课(第 1–3 章顺序读)
从「风格能不能被量化」开始,经三个可测维度、风格向量与风格距离矩阵、风格选择与项目约束的权衡,到像素风的分辨率与调色板上限、调色板量化与抗锯齿替代、像素 tile 预算,再到 2D 手绘的扁平色块与线宽规范、手绘资产的切分与复用。这条路径回答「风格怎么从形容词变成数字」。读完你能拿出一份风格向量定义、一个能算出两两距离的矩阵,和一套像素与手绘的参数规范。
路径 B:三维与渲染风格课(第 4–8 章顺序读)
从低多边形的面数与顶点预算开始,经平面着色与色块划分、引擎接入约束、NPR 的色阶带与描边参数、光照分层规范、写实 PBR 的通道打包与材质分区、写实的性能代价,到厚涂的笔刷与色域参数规范、手绘贴图的分层与复用,最后到体素的网格账、调色板与光照简化、引擎接入。这条路径回答「三维取向的风格各自要付什么代价」。读完你能拿出五套风格各自的参数规范与整数账。
路径 C:主题化与收官课(第 9–16 章顺序读)
从等距投影的整数变换开始,经等距 tile 与遮挡规则、二次元的色彩与线条规范、角色比例与面部规范,到暗黑的饱和度分级与亮度分布、清新的高明度低饱和调色板、复古赛博的霓虹调色板与发光溢出、主题切换与变体管理、品类与预算及可读性的关系,最后用 6 个主题包跑同一份规范、给出风格距离矩阵,并做三卷总收官。这条路径回答「同一份规范怎么在 6 套风格下都站得住」。读完你能拿出一张 6×6 风格距离矩阵、一份跨风格验收清单,和一条三卷合起来的完整回放。
常见问题速查
| 你想解决的问题 | 看哪节 |
|---|---|
| 风格到底能不能被量化?从哪三个维度量? | 01.1 |
| 风格向量怎么算?两个风格怎么比距离? | 01.2 |
| 给定项目约束,风格该怎么选? | 01.3 |
| 像素风的分辨率与调色板上限怎么定? | 02.1 |
| 调色板量化误差多大?抗锯齿怎么替代? | 02.2 |
| 像素 tile 该做多大、预算怎么算? | 02.3 |
| 2D 手绘的色块与线宽规范怎么定? | 03.1 |
| 手绘资产怎么切分、怎么复用? | 03.2 |
| 画质与笔触为什么跑不起来? | 03.3 |
| 低多边形的面数与顶点预算怎么算? | 04.1 |
| 平面着色的色块怎么划分? | 04.2 |
| 低多边形接进引擎有哪些约束? | 04.3 |
| 色阶带分几档?描边宽度怎么定? | 05.1 |
| 卡通渲染的光照分层怎么规范? | 05.2 |
| 哪些内容该看 graphics/ 而不是本书? | 05.3 |
| PBR 贴图的通道怎么打包? | 06.1 |
| 材质分区与细节层级怎么划? | 06.2 |
| 写实风格要付出多少性能代价? | 06.3 |
| 厚涂的笔刷与色域参数怎么规范? | 07.1 |
| 手绘贴图怎么分层、怎么复用? | 07.2 |
| 笔触质量为什么只能标 X? | 07.3 |
| 体素的网格与体素数怎么算? | 08.1 |
| 体素的调色板与光照怎么简化? | 08.2 |
| 体素资产怎么接进引擎? | 08.3 |
| 等距投影的 tile ↔ screen 变换怎么算? | 09.1 |
| 等距 tile 的遮挡顺序怎么定? | 09.2 |
| 等距资产制作有哪些硬约束? | 09.3 |
| 二次元的色彩与线条怎么规范? | 10.1 |
| 角色比例与面部怎么落成参数? | 10.2 |
| 二次元画质为什么跑不起来? | 10.3 |
| 暗黑风格的饱和度分级怎么定? | 11.1 |
| 亮度分布与对比度怎么量化? | 11.2 |
| 暗场景里怎么平衡噪声与可读性? | 11.3 |
| 清新治愈的高明度低饱和怎么定? | 12.1 |
| 圆角与柔和过渡的规范怎么写? | 12.2 |
| 多主题并存时一致性怎么维护? | 12.3 |
| 霓虹调色板与色彩分级怎么定? | 13.1 |
| 发光与溢出该怎么规范? | 13.2 |
| 主题切换与变体怎么管理? | 13.3 |
| 品类和美术预算之间是什么关系? | 14.1 |
| 品类怎么影响视觉可读性? | 14.2 |
| 资产怎么跨品类复用与移植? | 14.3 |
| 6 个主题包怎么从一份规范实例化? | 15.1 |
| 6 个主题怎么证明同源又可区分? | 15.2 |
| 风格迁移的边界在哪、代价多大? | 15.3 |
| 跨风格验收清单长什么样? | 16.1 |
| 三卷合起来,一份规范跑通了什么? | 16.2 |
| 这一套交付了什么、后面还有什么? | 16.3 |
卷三工具链命名约定
本卷所有 prism/ 文件一律用 st<章号>_ 前缀(如 config/st02_palette.json、sim/st02_quantize.py、core/src/st02/、core/test/st02_*.test.ts),因为《游戏美术与技术美术》的卷一是 sp、卷二是 ta。这样 node --test 'core/test/st02_*.test.ts' 只会命中本卷第 2 章的测试,不会交叉匹配另外两卷。
注意前缀不要写成裸 st*:node --test 接收的是 glob 而非目录,故必须写全 st<章号>_*.test.ts。另外 web/ 层的文件名前缀不在首位(build_st09_isometric.mjs / verify_st09_isometric.mjs),清点脚本要同时认这两套命名,否则 web 层会被统计成 0。
三卷共用同一份 config/visual_spec.json 作为唯一真源,6 个主题包在 config/sp16_themes.json(卷一落盘)。改一个 token,仿真、内核、浏览器看板三处结果都变;第 15 章再用 6 个主题包把这条链路回放六遍。
完整文件索引、逐层复现命令与排错顺序见附录 A 。
在进入正文之前,先用下面这段 S 层环境自检脚本确认运行时齐备——它同时适用于三卷,并额外检查本卷最关心的两个输入(卷一落盘的唯一真源与 6 个主题包)是否存在。把它保存为 prism/sim/st00_env_check.py 后运行 /opt/homebrew/bin/python3 sim/st00_env_check.py,会打印解释器路径、numpy / pandas / Pillow 版本、两个输入文件的状态、DCC 探测结果与 Node 版本,任一不满足即非 0 退出。
#!/usr/bin/env python3
# file: sim/st00_env_check.py
# tier: S
# verify: /opt/homebrew/bin/python3 sim/st00_env_check.py
"""环境自检(卷三):确认《游戏美术与技术美术》三卷需要的运行时都在,并打印 prism 能力阶梯。
本机有两个 python3,不要混:/opt/homebrew/bin/python3 = 3.14.6(带 numpy / pandas / PIL),
S 层仿真与 PIL 生成一律用它;/usr/bin/python3 = 3.9.6(系统自带,无 numpy/pandas)。
本机**没有** matplotlib / scipy / colour / cairosvg:图表一律纯 xml.etree 生成 SVG,图像一律
PIL 生成 PNG。卷三以「风格参数 + 量化 + 距离矩阵」为主,色彩派生量一律手写同一组常数,
跨语言按声明容差断言。
"""
from __future__ import annotations
import json
import os
import shutil
import subprocess
import sys
EXPECT_PY = "/opt/homebrew/bin/python3"
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
def main() -> int:
ok = True
# /opt/homebrew/bin/python3 是符号链接,比较时解析到真实二进制再判断
real = os.path.realpath(sys.executable)
print(f"python {sys.version.split()[0]} ({real})")
if real != os.path.realpath(EXPECT_PY):
print(f" 注意:正文脚本一律用 {EXPECT_PY},当前解释器不同")
try:
import numpy
import pandas
import PIL
print(f"numpy {numpy.__version__}")
print(f"pandas {pandas.__version__}")
print(f"Pillow {PIL.__version__}")
except ImportError as e: # noqa: BLE001
ok = False
print(f"FAIL 缺依赖:{e}(S 层与 PIL 生成需要 numpy / pandas / Pillow)")
for mod in ("matplotlib", "scipy", "colour"):
try:
__import__(mod)
print(f"{mod:<10} 已安装(本套不使用,图表与色度一律手写)")
except ImportError:
print(f"{mod:<10} 未安装(符合预期)")
# 卷三的输入是卷一落盘的唯一真源与 6 个主题包,缺一个后面全是噪音
for rel in ("config/visual_spec.json", "config/sp16_themes.json"):
path = os.path.join(ROOT, rel)
if os.path.exists(path):
with open(path, encoding="utf-8") as f:
keys = ",".join(sorted(json.load(f).keys()))
print(f"{rel:<26} OK keys={keys}")
else:
ok = False
print(f"{rel:<26} FAIL 缺失(卷三读它,卷一应先落盘)")
# 卷三仍不做真 DCC / 真渲染:这四个一律不在本机,正文对应处一律标 X
dcc = " ".join(f"{t}={'有' if shutil.which(t) else '无'}" for t in ("blender", "mayabatch", "3dsmax", "Substance"))
print(f"DCC {dcc}")
node = shutil.which("node")
if not node:
ok = False
print("FAIL node 未安装(P 层需要 Node 26 或更高)")
else:
ver = subprocess.run([node, "-v"], capture_output=True, text=True).stdout.strip()
major = int(ver.lstrip("v").split(".")[0])
note = "" if major >= 26 else " (低于 26,原生 TypeScript 不可用)"
print(f"node {ver}{note}")
ok = ok and major >= 26
print("prism 能力阶梯:S 仿真 / P 内核 / W 网页 / D 静态 / X 不可复现 / B 基准")
print("OK 环境就绪" if ok else "FAIL 环境不满足")
return 0 if ok else 1
if __name__ == "__main__":
raise SystemExit(main())
实跑 /opt/homebrew/bin/python3 sim/st00_env_check.py:
python 3.14.6 (/opt/homebrew/Cellar/python@3.14/3.14.6/Frameworks/Python.framework/Versions/3.14/bin/python3.14)
numpy 2.5.1
pandas 3.0.3
Pillow 12.3.0
matplotlib 未安装(符合预期)
scipy 未安装(符合预期)
colour 未安装(符合预期)
config/visual_spec.json OK keys=atlas,budget,contrastFloor10,contrastPairs,generated,project,specVersion,tokens,tolerance
config/sp16_themes.json OK keys=atlas,budget,contrastFloor10,contrastPairs,dims,distinguishableFloor10,note,project,specVersion,themes,weights
DCC blender=无 mayabatch=无 3dsmax=无 Substance=无
node v26.5.0
prism 能力阶梯:S 仿真 / P 内核 / W 网页 / D 静态 / X 不可复现 / B 基准
OK 环境就绪
这段脚本与卷一、卷二同源,是整套书稿的第一条可运行命令;本卷的 st<章号>_ 脚本都建立在它验证过的同一套运行时之上。完整文件索引与逐层复现命令见附录 A
。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。