1
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
# 抓大鹅草稿素材生成流水线 2026-05-10
|
||||
|
||||
## 1. 范围
|
||||
|
||||
本方案用于改造 `生成抓大鹅草稿` 的首版生成链路:点击按钮后先进入独立生成过程页,生成结束后自动进入抓大鹅草稿页,并在草稿页 `3D素材` Tab 预览本次生成的 3D 模型。
|
||||
|
||||
本次只把任意难度都收敛为 `3` 件物品。后续难度曲线恢复时,再把物品数、网格数和手动 3D 任务数量从配置中放开。
|
||||
|
||||
## 2. 前端流程
|
||||
|
||||
入口仍复用 `Match3DAgentWorkspace` 表单。点击 `生成抓大鹅草稿` 后:
|
||||
|
||||
1. 创建 Match3D session。
|
||||
2. 进入 `match3d-generating` 生成过程页。
|
||||
3. 过程页复用拼图生成页的 `CustomWorldGenerationView` 结构。
|
||||
4. 生成成功后自动进入 `match3d-result`。
|
||||
5. 生成失败时停留在生成过程页,允许重新生成或返回创作中心。
|
||||
|
||||
生成页步骤固定为:
|
||||
|
||||
```text
|
||||
生成物品名称 -> 生成素材图 -> 切割独立图片 -> 生成 3D 模型 -> 上传图片与模型资产 -> 写入草稿页
|
||||
```
|
||||
|
||||
生成页只展示题材和物品数量,不展示玩法规则说明。
|
||||
|
||||
## 3. 后端编排边界
|
||||
|
||||
外部模型和 OSS 上传全部由 `api-server` 编排,不进入 SpacetimeDB reducer。SpacetimeDB 继续只负责 Match3D 会话、草稿和作品 profile 的确定性写入。
|
||||
|
||||
`match3d_compile_draft` action 的后端顺序为:
|
||||
|
||||
1. 读取 session config。
|
||||
2. 将本次 MVP 的 `clearCount` 固定为 `3`,并同步用于草稿编译。
|
||||
3. 调用文本模型生成 `3` 个题材下的短物品名称。
|
||||
4. 调用项目当前图片链路 VectorEngine `gpt-image-2-all` 生成一张 `1:1` 素材图,提示词必须合入入口页选择的 `assetStylePrompt`。历史 `nanobanana2` 图片选项当前按项目统一决策回落到 VectorEngine,不重新接入 APIMart 图片网关。
|
||||
5. 将素材图按 `n*n` 网格切割成独立图片。当前 `3` 件物品使用 `2*2` 网格,取前 `3` 格。
|
||||
6. 将素材图和每张独立图片上传到 OSS,其中独立图片作为 Rodin 图生模型参考图。
|
||||
7. 对每张独立图片调用 Hyper3D Rodin Gen-2 图生模型,等待任务完成,读取 GLB 下载文件并转存到 `generated-match3d-assets`。
|
||||
8. 调用现有 SpacetimeDB compile procedure 写入草稿,并把本次生成的独立物品图片与模型文件引用序列化写入 `match3d_work_profile.generated_item_assets_json`。这一步对标拼图的 `save_puzzle_generated_images`:生成资产不能只挂在本次 HTTP response 上,否则退出结果页后从草稿架读取 `getMatch3DWorkDetail` 会丢失素材列表。
|
||||
9. 在 HTTP 返回的 draft/profile DTO 中附带本次生成的素材资产预览信息,模型生成成功时状态为 `model_ready`;后续重进草稿页时从 work profile 的持久化 `generatedItemAssets` 恢复同一批素材。
|
||||
|
||||
草稿生成阶段会调用 Hyper3D Rodin,并等待 GLB 模型文件可下载;不得把上游下载 URL 直接写入 Match3D profile,必须先转存 OSS,再保存 `/generated-match3d-assets/...` 引用。结果页 `3D素材` Tab 的重新生成按钮仍可手动触发 Rodin 任务,但正式持久化仍以后端草稿生成链路写入的模型文件为准。
|
||||
|
||||
## 4. 图片提示词
|
||||
|
||||
素材图提示词必须显式包含:
|
||||
|
||||
```text
|
||||
生成一张1:1图片
|
||||
生成2*2网格素材图
|
||||
整体画风遵循:...
|
||||
只绘制这些物品:...
|
||||
不要出现文字、水印、UI、边框
|
||||
```
|
||||
|
||||
`包含若干个物品名称` 在落地中解释为“按生成出的物品名称绘制对应主体”,不要求图片上写出物品名称。这样可以避免文字渲染污染切图和后续手动 3D 模型参考。
|
||||
|
||||
入口页内置风格参考图通过同一 VectorEngine `gpt-image-2-all` 能力生成,保存路径固定为:
|
||||
|
||||
```text
|
||||
public/match3d-style-references/clay-toy.png
|
||||
public/match3d-style-references/low-poly.png
|
||||
public/match3d-style-references/toy-plastic.png
|
||||
public/match3d-style-references/wood-carved.png
|
||||
public/match3d-style-references/voxel-block.png
|
||||
public/match3d-style-references/metal-mecha.png
|
||||
```
|
||||
|
||||
这些图片只作为入口页风格选择的视觉参考,不进入用户草稿资产,不替代生成时的物品素材图。
|
||||
|
||||
## 5. OSS 路径
|
||||
|
||||
新增 generated legacy prefix:
|
||||
|
||||
```text
|
||||
generated-match3d-assets
|
||||
```
|
||||
|
||||
建议对象分组:
|
||||
|
||||
```text
|
||||
generated-match3d-assets/{sessionId}/{profileId}/material-sheet/{taskId}/sheet.png
|
||||
generated-match3d-assets/{sessionId}/{profileId}/items/{itemSlug}/image.png
|
||||
generated-match3d-assets/{sessionId}/{profileId}/items/{itemSlug}/model/{taskUuid}/model.glb
|
||||
```
|
||||
|
||||
`itemSlug` 必须带 `itemId` 前缀,例如 `match3d-item-1-item`。中文物品名清洗后可能都退回 `item`,不能只用物品名做路径,否则多张切割图会写到同一个 object key,导致草稿页预览图全部一致。
|
||||
|
||||
HTTP DTO 同时返回 `imageSrc`、`imageObjectKey`、`modelSrc`、`modelObjectKey`、`modelFileName`、`taskUuid`、`subscriptionKey` 和 `status = model_ready`。前端模型预览不得直接请求裸 `/generated-match3d-assets/...` 路径;需要通过 `/api/assets/read-bytes` 读取模型字节,转成 Blob URL 后交给 Three.js GLTFLoader 加载,以绕开私有 bucket CORS。
|
||||
|
||||
## 6. 自动保存与草稿恢复
|
||||
|
||||
抓大鹅结果页的基础信息自动保存继续调用 `PUT /api/runtime/match3d/works/{profileId}` 更新名称、题材、描述、标签、封面、消除数和难度;该保存不得清空 `generated_item_assets_json`。SpacetimeDB `update_match3d_work` / `publish_match3d_work` 必须保留当前行的生成素材 JSON。
|
||||
|
||||
草稿架重进路径为:
|
||||
|
||||
```text
|
||||
草稿 Tab -> getMatch3DWorkDetail(profileId) -> Match3DResultView(profile.generatedItemAssets)
|
||||
```
|
||||
|
||||
因此 `map_match3d_work_summary_response` / `map_match3d_work_profile_response` 需要从 work profile snapshot 反序列化 `generated_item_assets_json` 并输出 `generatedItemAssets`。前端 `Match3DResultView` 仍保持现有优先级:本次生成流程内有 `draft.generatedItemAssets` 时用 draft;从草稿架重进没有 draft 时,用 `profile.generatedItemAssets`;两者都没有才回退到默认 3D 素材占位。
|
||||
|
||||
`3D素材` 详情页只保留:
|
||||
|
||||
1. 模型预览区:优先加载 `modelSrc` 对应 GLB,支持拖动旋转;没有模型时展示空预览。
|
||||
2. 素材名称输入。
|
||||
3. `重新生成` 按钮。
|
||||
|
||||
详情页不再展示参考图、用途、提示词、文生/图生切换、状态查询、下载列表、taskUuid 或 subscriptionKey。
|
||||
|
||||
## 7. 验收
|
||||
|
||||
建议执行:
|
||||
|
||||
```powershell
|
||||
npm run check:encoding
|
||||
npm run test -- src\services\miniGameDraftGenerationProgress.test.ts
|
||||
npm run test -- src\components\match3d-result\Match3DResultView.test.tsx
|
||||
npm run typecheck
|
||||
cargo test -p shared-contracts match3d --manifest-path server-rs\Cargo.toml
|
||||
cargo test -p spacetime-client match3d --manifest-path server-rs\Cargo.toml
|
||||
cargo test -p platform-oss --manifest-path server-rs\Cargo.toml
|
||||
cargo test -p api-server match3d --manifest-path server-rs\Cargo.toml
|
||||
cargo check -p api-server --manifest-path server-rs\Cargo.toml
|
||||
cargo check -p spacetime-client --manifest-path server-rs\Cargo.toml
|
||||
cargo check -p spacetime-module --manifest-path server-rs\Cargo.toml
|
||||
```
|
||||
|
||||
真实草稿生成需要本地私密环境配置 `VECTOR_ENGINE_API_KEY`、`HYPER3D_API_KEY` 和 OSS 访问变量。后端改动后使用 `npm run api-server` 启动,并检查 `/healthz`。
|
||||
Reference in New Issue
Block a user