Skip to content

proposal: 画风改为受控档位,像素与否自动判定 #475

Description

@johnnyzhang-eng

背景

画风是生成质量的主要变量之一,同一段提示词换一种画风,模型表现的差异远大于换措辞。当前产品把画风表达为一段自由文本,这段文本同时承担了两件本质不同的职责,而真正能约束风格的那条链路建好了却没有入口。

问题

一、自由文本同时决定了两件事,其中一件是二值管线开关。

_load_constraintsorchestrator/executor.py:97)从自由文本做子串匹配:

is_pixel = "pixel" in style.lower() or "像素" in style
stylize = "pixel" if is_pixel else "none"

Stylize 不是「画得像什么」,而是「生成帧要不要按母版的原生像素块大小降采样、并把颜色吸附回母版色板」(postprocess/pixelate.py)。写「复古 8bit」「点阵风」「low-res sprite」都推不出 pixel,像素角色于是走 LANCZOS 重采样,硬边被糊成灰边并引入色板外颜色。猜错是静默的——帧数、时长、成色全部正常,没有一道会红。

二、风格参考图后端全链路已通,前端零入口。

sprite_sample_urlProject 模型、API 出入参、到 ProjectConstraints、再到 _produce_image 的图生图分支全部就绪。但前端只有 DTO 字段映射,没有任何页面能设置它。这条已建成的链路当前不可达。

三、Quick Start 从不设置画风。

createAutoPrepareProjectfrontend/src/pages/quick-start/service.ts:814)建项目时只传 name、perspective、directionalMovement、spriteSize。走 Quick Start 建的项目 game_style 恒为 null,而它是当前主推入口。

四、画布上画风只读。

workflow-editor-view.tsx:61project.gameStyle ?? '未设置画风' 放进左下角约束条。用户看得到「未设置画风」,但没有入口能改。

竞品怎么做

像素密度 画风 体型 参考图
PixelLab size: int,默认 48 detail / shading / outline 三条正交枚举 proportions:default / chibi / cartoon / stylized / realistic_male / realistic_female / heroic Bitforge 支持
Retro Diffusion width / height 任意 约 15 个具名预设下拉 支持,且可传强制调色板
评论中贴的友商 16 / 24 / 32 / 48 / 64px 简约 / 中等 / 精致 Q版 / 等身

三条可借鉴的:

  1. PixelLab 把体型比例(chibi / realistic)单独成轴,不混进画风。真实与否首先是身高头身比,其次才是渲染方式。
  2. PixelLab 的 detail / shading / outline 相互正交,不压成一维。
  3. 三家都支持参考图,RD 还支持强制调色板 —— 我们实测三个生图模型色数全部顶到 256,没有一个做限色。

友商那份清单的问题(也是评论里指出「会有点乱」的原因):它把像素密度、资产类型、体型比例三件事塞进同一个清单,于是 32px 出现了 5 次(简约像素角色、简约Q版角色、简约等身角色、简约像素道具、简约像素武器)。

一条不采纳的:三家都用具体像素数字,我们不该跟。它们是专用像素模型,size=48 就真出 48px;我们用通用模型,实测提示词要 32px 时实际逻辑高中位 97、范围 51181,要 64px 时中位 171、范围 93275。两档拉得开,但绝对值接不住——给用户一个我们兑现不了的数字是承诺不履约。所以用档位不用数字。

实测

像素与否可以自动判定,不必问用户。 detect_pixel_size(母版) >= 2 在 12 张生成像素图与 5 张归档非像素图上判对 17/17,且分离干净:像素图块大小 6~25,非像素图全部恰好为 1,中间无样本。master_pixel_spec 的 docstring 也写明逻辑像素高「不必人肉猜分辨率」。

画风不影响抠图难度。 三种非像素画风(卡通 / 手绘 / 厚涂写实)× 三个生图模型 × 每格 4 张,共 36 张:

净抠穿面积
gemini-2.5-flash-image 0.05%
gemini-3.0-pro-image-preview 0.01%
gemini-3.1-flash-image-preview 0.01%

按画风分组同样全部 ≤0.15%。没有任何一格出现真正的抠穿。

这里要说明读数口径:一开始用的是「主体内孔洞占比」,读出卡通 8.12% / 手绘 23.69% / 厚涂 1.45%,看似差异巨大。逐张看图后发现它测的是构图不是抠图——高值全部来自半透明披风、叉腿站姿的腿间空隙、纸张底纹,这些本来就该透明。改用「净抠穿面积」(孔洞处像素离底色比主体第 25 百分位还远的比例 × 孔洞面积)后,差异消失。另外单模型与两模型并集对比,并集只补 0.0~2.9 个百分点,说明剩下的孔洞不是漏检。

所以画风分档不能拿管线找依据 —— 卡通、手绘、写实在管线里走同一条路(stylize=none),抠图难度也没有实质差异。它们该分开的唯一理由是用户能看出区别:卡通有粗描线平涂、手绘有笔触与纸纹、厚涂无描线渐变,三者一眼可辨。一个想要卡通描线的用户拿到厚涂写实,就是没被满足。

方案

画风预设(单选,默认「自动」)
├ 自动                        ← 由母版量出像素与否,不问用户
├ 低像素 / 中像素 / 高像素      ← stylize = pixel
├ 卡通                        ┐
├ 手绘                        ├ stylize = none
└ 写实                        ┘

体型(独立轴,不与画风混)      等身 / Q版
画风补充描述(自由文本)        温馨 / 中世纪 / 日系…不做枚举
项目参考图(图)                复用已有的 sprite_sample_url,补前端入口

四条设计判据:

  1. 「自动」当默认。用户建项目时未必想清楚,而母版一旦生成,像素与否是客观事实;它也覆盖用户上传母版的场景。用户显式选择时以用户为准——有一种情况自动会判错:用户想要像素资产却传了一张非像素母版,那时他要的是「把它像素化」。
  2. 像素给档位不给数字,理由见上。档位只影响生成母版时的提示词,不进后处理参数——master_pixel_spec 会从母版自己量。
  3. 体型单独成轴,跟 PixelLab 一致。混进画风会让「写实」既表示渲染方式又表示身材比例。
  4. 题材气质不做枚举。温馨、中世纪、日系这类只影响提示词文字,不触发任何管线分支,做成枚举等于把无限的描述空间硬塞进几个格子。受控枚举只给用户需要明确表达、且我们能兑现的区分。

不包含

  • 不做每种画风的提示词调优,不判断哪个模型更擅长哪种画风——那属于 proposal: 建立生图与视频模型的选型判据与实验规程 #465
  • 不改动生成链路的默认模型。
  • 动作生成接入风格参考图不在本 Issue:executor.py:331 注释写明「视频 i2v 没有独立的 style reference 字段」,需要先确认 i2v 侧有没有可用入口。

需要对齐

  1. 像素三档与卡通/手绘/写实是否放在同一个下拉,还是先选「像素/非像素」再选细分。前者选项共 7 个,后者多一次点击。
  2. 体型轴放不放进本期。它是新字段,Project 目前没有对应位置。
  3. 参考图与画风文字冲突时听谁的。
  4. 存量项目的自由文本如何迁移。 已有的 game_style 是自由文本,需要兼容读法或一次迁移。

验收

  1. Quick Start 能设置画风,所建项目的 game_style 不再恒为 null。
  2. 画布左下角的画风可编辑,不再是只读展示。
  3. Stylize 由显式档位或自动判定决定,不再对自由文本做子串匹配。
  4. 项目参考图在前端可设置,且母版生成确实走了图生图分支。
  5. 有一条测试锁住「选了像素档的项目,序列帧走 NEAREST 且颜色吸附回母版色板」。

Metadata

Metadata

Labels

proposal该 Issue 是一个产品提案

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions