Qwen-Image2.1游戏素材工坊:把整套素材拼成"模拟游戏画面"逐张体检 (二)
2026-10-26 · 项目地址
https://github.com/wyfirstname/qwenimage-comic
分类页签画幅有据可查仿真测试运行时实测
之前写过后半句——"AI 批量出游戏素材"的流水线(提示词方案 → 生成 → 透明底 → 色调校验 → 导出)。今天这一轮改造解决的是更前面的问题:图生得再好看,没放回游戏里跑过,就不知道它能不能用。
0. 今天改了什么
| 版本 | 主要改造 | 一句话 |
|---|---|---|
| 6.0 | 分类页签 | 角色/宠物/场景分页签管理,主角分男女,每类提示词独立可调 |
| 7.0 | 画幅有据可查 | 怪物分四级、场景按用途定画幅(横版 16:9 / 平铺 1:1 / 立绘 2:3…),每档都写明理由 |
| 8.0 | 仿真测试 | 把整套素材拼成"模拟游戏画面"逐张体检 |
| 9.0 | 运行时实测 | rembg 真抠图 + 场景可行走区域识别 + canvas 真碰撞跑图 |
上午的 6.0/7.0 是"排版升级":面板更细、每个决策有依据。真正的转折在下午收到一句反馈——
就目前来说质量太差了。主角图片非透明图片,场景图片中道路如何识别,哪些位置可以行走……建议结合之前破解游戏的经验把素材放进去实测,把整个流水线打通。
这句话把三个此前"假装解决了"的问题全部点破。9.0 就是冲着它去的。
1. 8.0 仿真测试:先把图"拼"成一张游戏画面
原来的验收方式是逐张看大图——单张都还行,凑到一起才发现比例失调、色调漂移、白底没抠。所以第一步不是修图,是让它们先出现在同一张画面里。
simulator.py 做的事:按 场景 × 季节 分组,每组用 PIL 合成一张 1280×720 的模拟游戏画面:
- 场景图打底(cover 铺满)
- 建筑压在远角做层次
- 怪物按等级定大小(杂兵 92px → 精英 138 → 首领 196 → 终局 290,与生成侧的画幅预设同源,等级是看得见的体积信号)
- 主角站前台、宠物在脚边
- 武器进底部"假动作栏",最后盖一层 HUD

合成的同时做逐张体检,四项硬指标:
- 文件存在;
- 画幅与设计方案一致;
- 该透明的类真有 alpha(不是白底矩形);
- 色调达标(与锚定基准的色距)。
对存量素材跑了一遍:13/16 张不达标——全是旧画幅、没抠底、跑色。这个数字很难看,但正是仿真测试的价值:问题第一次被系统地暴露出来,而不是靠人眼一张张瞪。
2. 9.0:把三层真正打通
2.1 抠图:色键抠不动白衣
之前的透明底用的是白底色键(chroma)——对深色素材够用,但主角偏偏是白袍白底:白色像素本身就是主体,色键一抹全没(实测 alpha_ratio 只有 0.012)。之前"主角非透明图片"的根子就在这。
解法是换成 rembg(U2Net,167MB 模型本地已有),并且不盲信它:
def matte(src, dst, method="rembg") -> dict:
# rembg 优先,结果退化自动回落色键
try:
rep = _via_rembg(src, dst)
except Exception as exc: # 依赖/模型缺失 → 色键兜底
rep = _via_chroma(src, dst)
rep.update({"fallback": True, "rembg_error": str(exc)[:160]})
return rep
ratio = rep.get("alpha_ratio", 0)
if 0.02 <= ratio <= 0.97: # 抠没了 / 没抠动 都算失败
rep["fallback"] = False
return rep
fb = _via_chroma(src, dst)
fb.update({"fallback": True, "rembg_alpha_ratio": ratio,
"rembg_error": f"rembg 结果退化(透明占比 {ratio})"})
return fb
报告里还加了一个 halo 指标:半透明边缘像素与主体的平均亮度差,正数说明边缘泛白(白晕没洗干净)。配套加了 POST /assets/{aid}/recut(单张重抠)和 POST /sets/{sid}/recut(整集批量重抠),旧图自动进历史版本。

同一张图,色键把整个白衣人物吃掉,rembg 完整保留——批量重抠 7 张存量素材,零回落。
2.2 场景语义:哪里能走
破解游戏的经验在这里直接复用:任何 2D 游戏的场景图旁边必然挂着一张碰撞层。AI 生成的概念图没有,那就自己算一张。scene_analysis.py 的思路:
- 地平线检测——自上而下找"多数像素明显偏离天空参考色"的行;横版图按用途钳制下限(云海场景容易误判),平铺/等距图直接走 topdown 模式(全域只抠障碍);
- 地面主色聚类——底部 18% 行的中位色当"路面参考色";
- 三条件判可走:与路面色距近 + 纹理平坦(局部梯度低)+ 不是近黑阴影;
- 形态学去噪、填洞,只保留最大连通域。
# 纯 numpy,单张 <1s
_COLOR_TOL, _EDGE_TOL, _DARK_LUM, _MASK_W = 46.0, 26.0, 42.0, 256
dist = np.sqrt(((arr - ground_ref) ** 2).sum(axis=2)) # 与路面主色的色距
edge = _edge_map(arr) # 局部梯度:纹理平坦才算路面
lum = arr.mean(axis=2)
walk = (dist < _COLOR_TOL) & (edge < _EDGE_TOL) & (lum > _DARK_LUM)
walk[:horizon, :] = False # 天空/远景不可走
walk = _clean(walk) # 去噪 + 填洞 + 取最大连通域
产出三样东西:walk mask(256 宽 PNG,运行时直接采样)、绿/红叠加预览(给人眼复核用)、meta(地平线、可行走占比、战斗带、3 个出生点、主要障碍框)。

青冥峰顶的山路被标绿、崖壁算障碍;幽墟秘林的林间地面同样成立。
2.3 运行时实测:真碰撞跑图
这是今天最重要的一块:playtest.html,一个真正的 canvas 运行时,不再是拼图——
- 场景打底,walk mask 逐格碰撞;没掩码不设限,有掩码严格按格判定
- 自动机器人:BFS 寻路走向每只野怪,撞墙贴滑、卡死重规划;全程记录碰撞违规
- 实时指标面板:碰撞层加载、出生点合法性、野怪可达、碰撞违规、脚底是否落在战斗带、每个精灵是否真有透明底
- 按 M 叠加显示碰撞层;WASD 随时手动试玩
- 实测结束把报告
POST回后端落库、写日志


对真实项目「云巅剑域」的实测结论:PASS——出生点合法、2/2 野怪可达、0 碰撞违规、全程 4 秒。这个报告现在每次点"开始实测"都会重新生成并入库,素材好不好,跑一遍就知道。
3. 三个坑(每个都花了不少时间)
坑一:alpha 极值误判。 体检最初用"四角/边缘最小 alpha < 250"判断图有没有透明像素。但引擎出图自带一个几乎不透明的 alpha 通道(min≈208),于是所有图都"有 alpha",白底矩形全漏检。改成按透明像素占比统计才对。教训:PNG 带 alpha 通道 ≠ 内容真的透明。
坑二:round 与 floor 打架。 机器人写好后原地不动——路径明明算出来了。逐层排查发现:寻路按格子中心(mx + 0.5)算,而 walkAt 里坐标换算用了 Math.round,中心值被舍入到隔壁格;寻路说这格能走、移动探测却探到隔壁的墙,机器人卡在"能走但走不动"的死循环里。统一改成 Math.floor 后 4 秒跑完全程。教训:同一张网格上的两套坐标换算,必须用同一个取整约定。
- const mx = Math.round((cx / cover.s + cover.ox) / state.sceneW * state.maskW);
+ const mx = Math.floor((cx / cover.s + cover.ox) / state.sceneW * state.maskW);
坑三:门户静态路径 404。 "进场景实测"按钮里写死了 /playtest.html,独立跑没事;门户把前端挂在 /apps/gameassets/ 下,这个地址必然 404。改成按当前页路径推导本站目录(siteDir()),同时把页面里的"← 工坊"从根路径改成相对 index.html。
4. 数字收尾
- 9.0 单次提交:8 个文件,+1088 行(scene_analysis.py + playtest.html 是大头)
- 体检/仿真:16 张素材 4 项指标、8 组模拟画面,纯 CPU 秒级
- 抠图:存量 7 张 rembg 重抠,0 回落
- 实测:PASS(2/2 可达、0 违规、4s);浏览器 E2E 全绿、无 JS 报错
- 便携包 F:\qwenimage 同步 + 包内 Python 冒烟通过
5. 还差什么
- 可行走分析是启发式 v1:横版概念图够用,复杂透视场景还得靠分割模型升级;
- 前景遮挡(树挡人)没做 z-order 分层,合成画面里主角永远在最上层;
- 下一步想把实测报告接回方案生成:画幅不对 → 自动改方案重生成,让"实测"从验收环节变成闭环的一环。
一天的结论:素材流水线的最后一公里,不在生成端,在运行时。 图放进游戏里跑通的那一刻,所有质量问题才有坐标。

浙公网安备 33010602011771号