# Hyper3D Rodin Gen-2 3D 模型生成接入方案 2026-05-08 ## 1. 范围 本方案用于接入 Hyper3D Rodin Gen-2 的文生 3D 模型与图生 3D 模型能力。 本次只做后端安全代理与前端可复用 client,不新增 SpacetimeDB 表,不落正式资产对象,不把 Hyper3D API Key 下发到前端。生成结果仍由调用方在拿到下载链接后决定是否进入 OSS / `asset_object` 的正式资产链。 ## 2. 参考接口 参考文档: - `https://developer.hyper3d.ai/api-specification/rodin-generation-gen2` - `https://developer.hyper3d.ai/api-specification/check-status` - `https://developer.hyper3d.ai/api-specification/download-results` - `https://developer.hyper3d.ai/api-specification/check-status_reset_v` - `https://developer.hyper3d.ai/api-specification/download-results_reset_v` 上游接口: ```text POST https://api.hyper3d.com/api/v2/rodin POST https://api.hyper3d.com/api/v2/status POST https://api.hyper3d.com/api/v2/download ``` Rodin Gen-2 提交接口必须使用 `multipart/form-data`。文本生成时提交 `prompt`;图片生成时提交一个或多个 `images` 文件,可选 `prompt` 作为辅助描述。两种模式均固定提交 `tier=Gen-2`。 官方 `*_reset_v` 文档对状态和下载有两个关键约束: 1. 生成接口返回的顶层 `uuid` 是后续下载接口的 `task_uuid`,不要使用 `jobs.uuids` 中的子任务 uuid 作为下载参数。 2. 状态接口使用 `subscription_key` 查询,并返回 `jobs[]`;只有所有 job 的 `status` 都为 `Done` 才能进入下载,任一 job `Failed` 都应视为任务失败。 ## 3. 环境变量 ```text HYPER3D_BASE_URL=https://api.hyper3d.com/api/v2 HYPER3D_API_KEY= HYPER3D_MODEL_REQUEST_TIMEOUT_MS=180000 ``` 兼容变量: ```text RODIN_BASE_URL RODIN_API_KEY RODIN_MODEL_REQUEST_TIMEOUT_MS ``` 说明: 1. `HYPER3D_API_KEY` / `RODIN_API_KEY` 只允许写入本地或生产私密环境,不提交到 Git。 2. 缺少 API Key 时,后端返回 `503 SERVICE_UNAVAILABLE`。 3. 本地真实联调推荐把 key 放在 `.env.secrets.local`;`npm run api-server`、`npm run dev:rust` 与 `npm run dev` 均应保持“外层 shell 变量优先,随后 `.env`、`.env.local`、`.env.secrets.local` 逐层覆盖”的口径,避免 `.env` 里的空示例值压掉私密 key。 4. `HYPER3D_BASE_URL` 默认使用公开 API 基础地址;如果团队后续改用代理网关,可通过环境变量覆盖。 ## 4. 后端路由 新增 4 个鉴权路由: | 方法 | 路由 | 用途 | | --- | --- | --- | | `POST` | `/api/assets/hyper3d/text-to-model` | 提交 Rodin Gen-2 文生模型任务 | | `POST` | `/api/assets/hyper3d/image-to-model` | 提交 Rodin Gen-2 图生模型任务 | | `POST` | `/api/assets/hyper3d/status` | 使用 `subscriptionKey` 查询任务状态 | | `POST` | `/api/assets/hyper3d/download` | 使用 `taskUuid` 获取模型下载列表 | 文生模型请求最小体: ```json { "prompt": "一只低多边形宝箱,适合 RPG 游戏资产", "geometryFileFormat": "glb", "material": "PBR", "quality": "medium", "meshMode": "Quad", "previewRender": true } ``` 图生模型请求最小体: ```json { "imageDataUrls": ["data:image/png;base64,..."], "prompt": "保留主体轮廓,生成游戏可用 3D 模型", "conditionMode": "concat", "geometryFileFormat": "glb" } ``` ## 5. 约束 1. 图片只接受 `data:image/png|jpeg|webp;base64,...`,最多 5 张。 2. 单张图片解码后不超过 10MB。 3. `geometryFileFormat` 限定为 `glb/usdz/fbx/obj/stl`,默认 `glb`。 4. `material` 限定为 `PBR/Shaded/All`,默认 `PBR`。 5. `quality` 限定为 `high/medium/low/extra-low`,默认 `medium`。 6. `meshMode` 限定为 `Quad/Raw`,默认 `Quad`。 7. `addons` 首版只允许 `HighPack`。 8. `bboxCondition` 必须为 3 个正数,按上游要求序列化为 JSON 字符串。 9. `subscriptionKey` 是 Hyper3D 返回的 opaque token,状态查询只校验非空,不在本地做 256 字符等固定长度限制,避免长 token 阻断抓大鹅草稿内联模型生成。 ## 6. 返回语义 提交任务成功后返回: ```json { "ok": true, "provider": "hyper3d-rodin", "mode": "text-to-model", "taskUuid": "task-uuid", "subscriptionKey": "subscription-key", "jobUuids": ["job-uuid"], "message": "Submitted.", "tier": "Gen-2" } ``` 状态查询会把上游 `Waiting / Generating / Done / Failed` 归一化为 `waiting / generating / done / failed / unknown`,整体状态必须以 `jobs[]` 聚合结果为准。下载接口只返回上游 `list.name` 与 `list.url`,不在 Hyper3D 代理路由中转存文件;具体玩法若需要持久化模型,应在玩法编排层等待 `Done` 后再下载并转存。 ## 7. 验收 建议执行: ```bash npm run check:encoding npm run typecheck cd server-rs cargo test -p shared-contracts hyper3d cargo test -p api-server hyper3d cargo check -p api-server ``` 真实 API smoke 只在本地私密环境设置 `HYPER3D_API_KEY` 后执行。提交生成任务会消耗 Hyper3D Credit,默认验证不自动调用真实生成接口。