帮你快速理解、总结文档立即下载

3D 生成模型

最近更新时间:2026-08-31 17:58:47
我的收藏

功能简介

腾讯云媒体处理(MPS)AIGC 聚合平台提供 3D 大模型生成 服务,支持通过文字描述(文生 3D)、单张图片(图生 3D)或多视角图片(多视角图生 3D)生成高质量的 3D 模型资产。生成的 3D 模型包含几何体和纹理,支持输出 OBJ、GLB 等主流格式,可直接用于短剧、电商展示、AR/VR 等场景。开发者通过同一套 API 即可调用不同模型并获取生成结果。

计费说明

通过媒体处理产品调用 AI 3D 生成,统计成功生成的任务结果的时长,计费单位是秒。各类型计费规则的完整说明可参考 按量计费 文档。

前置条件

1. 开通服务

1. 登录 腾讯云媒体处理控制台,按照引导开通 MPS 服务。
2. 获取 API 密钥:前往 API 密钥管理 获取 SecretId 和 SecretKey。
3. (可选)如需将生成结果存到 COS,还需开通对象存储 (COS) 并创建存储桶,授权 MPS_QcsRole 角色。可参考 账号授权相关 文档。

2. 安装依赖

本指南的代码示例使用 axios 作为 HTTP 客户端,但它不是必须的。您可以根据项目情况选择以下任一方式发送 HTTP 请求。
方案
是否需要安装
适用场景
axios(本文示例默认)
npm install axios
已有项目在用 axios,或偏好其 API 风格。
Node.js 原生 fetch
无需安装(Node.js ≥ 18 内置)
零依赖、现代项目推荐。
Node.js 原生 https
无需安装
兼容老版本 Node.js(< 18)。
如果您选择 axios
npm install axios
如果您选择原生 fetch(Node.js ≥ 18,零依赖),将代码中的 axios.post(...) 替换为:
// 替换 axios.post 调用
// 原: const resp = await axios.post(`https://${MPS_HOST}`, payload, { headers });
// return resp.data;
// 改为:
const resp = await fetch(`https://${MPS_HOST}`, {
method: 'POST',
headers: headers,
body: JSON.stringify(payload)
});
return await resp.json();

说明:
Node.js 内置的 crypto 模块即可完成签名,无需额外安装。签名部分无外部依赖。

3. 密钥配置

{
"tencentCloud": {
"secretId": "您的 SecretId",
"secretKey": "您的 SecretKey",
"region": "ap-guangzhou"
}
}
注意:
安全提醒:密钥绝对不要硬编码到代码中或提交到 Git,建议使用环境变量或独立的配置文件(加入 .gitignore)。

API 概览

核心能力
接口
Action
说明
并发限制
文生3D
SubmitHunyuan3DTask
QueryHunyuan3DTask
通过文字 Prompt 描述,生成完整 3D 模型(几何 + 纹理)
1
图生 3D
上传一张参考图片,生成对应 3D 模型
1
多视图生 3D
提供多角度图片(正/背/左/右等),还原度最高
1
说明:
通用信息:
请求域名:mps.tencentcloudapi.com
请求方式:POST(application/json)
API 版本:2019-06-12
签名方法:TC3-HMAC-SHA256
关键约束:
入参 Prompt / ImageUrl / MultiViewImages 三选一,必填其一,互斥,不可同时传入。
并发生成任务数默认为1并发/主账号。
MultiViewImages 至少2张(2~8 张),且必须包含 front 视角,同一 ViewType 不允许重复。

签名机制 (TC3-HMAC-SHA256)

腾讯云 API 3.0 使用 TC3-HMAC-SHA256 签名认证。签名过程如下:
1. 构建规范请求 (CanonicalRequest):拼接请求方法、URI、QueryString、Headers、Payload Hash。
2. 构建待签字符串 (StringToSign):拼接算法、时间戳、CredentialScope、CanonicalRequest Hash。
3. 计算签名 (Signature):用 SecretKey 逐级 HMAC 派生签名密钥,再对 StringToSign 签名。
4. 构建 Authorization Header:组装最终的认证头。

注意事项

1. 生成结果仅存储24小时
图片和视频的 URL 只有12小时有效期,务必在生成后及时下载或转存到自己的 COS/服务器。
2. 频率限制
几何(白模)生成:1并发
3D 模型(带纹理)生成:1并发
建议实现并发控制和请求队列,避免触发限流。
3. 图片输入要求
大小 ≤ 10MB,分辨率短边 ≥ 512、长边 ≤ 4096。
支持格式:JPGJPEGPNGWEBP
图片 URL 必须外网可访问。
4. Prompt 长度限制
字符限制:不超过 1024 utf-8 字符。
描述建议:使用具体、有画面感的描述(主体 + 风格 + 颜色 + 姿态),避免抽象概念与多主体。
5. COS 存储
使用 StoreCosParam 可将结果直接存到指定 COS 桶,需要:
开通 COS 服务。
创建存储桶。
授权 MPS_QcsRole 角色访问该桶。

核心代码实现

1. 签名工具 (tencent-sign.js)

/**
* 腾讯云 API 签名工具 (TC3-HMAC-SHA256)
*/
const crypto = require('crypto');

function sha256(message) {
return crypto.createHash('sha256').update(message).digest('hex');
}

function hmac256(key, message) {
return crypto.createHmac('sha256', key).update(message).digest();
}

/**
* 生成腾讯云 API V3 签名
* @param {string} secretId - 腾讯云 SecretId
* @param {string} secretKey - 腾讯云 SecretKey
* @param {string} service - 服务名,如 'mps'
* @param {string} action - 接口名,如 'CreateAigcVideoTask'
* @param {string} payload - 请求体 JSON 字符串
* @param {string} region - 地域,如 'ap-guangzhou'
* @param {string} [version] - API 版本号,默认 '2019-06-12'
* @returns {{ headers: object }} - 包含完整签名的请求头
*/
function signRequest(secretId, secretKey, service, action, payload, region, version) {
const timestamp = Math.floor(Date.now() / 1000);
const date = new Date(timestamp * 1000).toISOString().split('T')[0];

// ===== 步骤1: 拼接规范请求串 =====
const httpRequestMethod = 'POST';
const canonicalUri = '/';
const canonicalQueryString = '';
const contentType = 'application/json';
const canonicalHeaders =
`content-type:${contentType}\\n` +
`host:${service}.tencentcloudapi.com\\n` +
`x-tc-action:${action.toLowerCase()}\\n`;
const signedHeaders = 'content-type;host;x-tc-action';
const hashedRequestPayload = sha256(payload);
const canonicalRequest =
`${httpRequestMethod}\\n${canonicalUri}\\n${canonicalQueryString}\\n` +
`${canonicalHeaders}\\n${signedHeaders}\\n${hashedRequestPayload}`;

// ===== 步骤2: 拼接待签名字符串 =====
const algorithm = 'TC3-HMAC-SHA256';
const credentialScope = `${date}/${service}/tc3_request`;
const hashedCanonicalRequest = sha256(canonicalRequest);
const stringToSign =
`${algorithm}\\n${timestamp}\\n${credentialScope}\\n${hashedCanonicalRequest}`;

// ===== 步骤3: 计算签名 =====
const secretDate = hmac256(`TC3${secretKey}`, date);
const secretService = hmac256(secretDate, service);
const secretSigning = hmac256(secretService, 'tc3_request');
const signature = crypto.createHmac('sha256', secretSigning)
.update(stringToSign).digest('hex');

// ===== 步骤4: 拼接 Authorization =====
const authorization =
`${algorithm} Credential=${secretId}/${credentialScope}, ` +
`SignedHeaders=${signedHeaders}, Signature=${signature}`;

return {
headers: {
'Authorization': authorization,
'Content-Type': contentType,
'Host': `${service}.tencentcloudapi.com`,
'X-TC-Action': action,
'X-TC-Timestamp': String(timestamp),
'X-TC-Version': version || '2019-06-12',
'X-TC-Region': region || ''
}
};
}

module.exports = { signRequest };

2. MPS API 封装 (mps-api.js)


// mps-api.js — 混元 3D 生成 API 封装(Node.js ≥ 18,原生 fetch,零依赖)
const { signRequest } = require('./sign');

const SERVICE = 'mps';
const VERSION = '2019-06-12';
const REGION = 'ap-guangzhou';
const ENDPOINT = 'mps.tencentcloudapi.com';

const SECRET_ID = process.env.TENCENTCLOUD_SECRET_ID;
const SECRET_KEY = process.env.TENCENTCLOUD_SECRET_KEY;

/** 通用调用:签名 → 发请求 → 校验错误 → 返回 Response */
async function callMpsApi(action, params) {
const payload = params || {};
const { authorization, timestamp } = signRequest({
secretId: SECRET_ID,
secretKey: SECRET_KEY,
action,
payload,
});

const res = await fetch('https://' + ENDPOINT + '/', {
method: 'POST',
headers: {
Authorization: authorization,
'Content-Type': 'application/json',
'X-TC-Action': action,
'X-TC-Timestamp': String(timestamp),
'X-TC-Version': VERSION,
'X-TC-Region': REGION,
},
body: JSON.stringify(payload),
});

const data = await res.json();
const r = data.Response || {};

// 业务错误:先看标准错误信封 Error.Code,再看扁平 ErrorCode(如 ResourceNotFound.TaskId)
if (r.Error || r.ErrorCode) {
const code = (r.Error && r.Error.Code) || r.ErrorCode;
const message = (r.Error && r.Error.Message) || r.ErrorMessage;
throw new Error(`${action} failed: ${code} - ${message} (RequestId: ${r.RequestId})`);
}
return r;
}

/**
* 提交 3D 生成任务(文生 / 图生 / 多视角图生,入参三选一,互斥)
* @param {object} params
* @param {string} [params.Prompt] 文生 3D 提示词,最长 1024 utf-8 字符
* @param {string} [params.ImageUrl] 图生 3D 参考图 URL(jpg/jpeg/png/bmp/webp,
* 短边 ≥ 512、长边 ≤ 4096、建议 ≤ 10MB,须公网可访问)
* @param {Array<{ViewType: string, ViewImageUrl: string}>} [params.MultiViewImages]
* 多视角图生 3D:2~8 张,必须包含 front 视角,ViewType 不可重复。
* 可选值:front / back / left / right / top / bottom / left_front / right_front
* @param {string} [params.GenerateType='Normal'] Normal:完整 3D 资产(几何+纹理);
* Geometry:仅几何(更快,约 40s)
* @param {boolean} [params.EnablePBR=false] 是否输出 PBR 材质
* @param {number} [params.FaceCount=500000] 面片数,范围 [3000, 1500000]
* @returns {Promise<{TaskId: string, RequestId: string}>}
* TaskId:任务唯一 ID,用于后续查询;RequestId:请求追踪 ID,定位问题请提供此 ID
*/
async function submitHunyuan3DTask(params) {
return callMpsApi('SubmitHunyuan3DTask', params);
}

/**
* 查询 3D 生成任务
* @param {string} taskId Submit 返回的任务 ID
* @returns {Promise<{
* Status: 'WAIT' | 'RUN' | 'DONE' | 'FAIL',
* Progress: number,
* ErrorCode?: string, // 仅 FAIL 时返回,如 InternalError.ModelInference
* ErrorMessage?: string, // 仅 FAIL 时返回
* ResultFile3Ds?: Array<{ // 仅 DONE 时返回
* Type: 'OBJ' | 'GLB' | 'MTL' | 'OBJ_ZIP',
* Url: string,
* PreviewImageUrl?: string
* }>,
* RequestId: string
* }>}
* ⚠️ ResultFile3Ds 中的 Url 为临时签名 URL,有效期约 24 小时,请及时下载或转存。
* 默认输出 OBJ + GLB 两种格式,其中 OBJ 同时提供单独文件和含 MTL+纹理的 ZIP 包。
*/
async function queryHunyuan3DTask(taskId) {
return callMpsApi('QueryHunyuan3DTask', { TaskId: taskId });
}

module.exports = { submitHunyuan3DTask, queryHunyuan3DTask };


完整使用流程

本接口为异步任务模式,一次生成分两步:提交任务(Submit)→ 轮询查询(Query)。Status 状态流转为 WAIT → RUN → DONE / FAIL。

1. 文生 3D(根据 Prompt 生成带纹理的几何模型)

文字描述生成完整的 3D 模型(几何 + 纹理):

const { submitHunyuan3DTask, queryHunyuan3DTask } = require('./mps-api');

async function main() {
// ① 提交任务
const submitResp = await submitHunyuan3DTask({
Prompt: 'a cute cartoon dinosaur, green, small horns',
FaceCount: 500000,
});
const taskId = submitResp.TaskId;
console.log('TaskId:', taskId);

// ② 每 8 秒轮询一次
while (true) {
const r = await queryHunyuan3DTask(taskId);
console.log('Status:', r.Status, 'Progress:', r.Progress);

if (r.Status === 'DONE') {
// ⚠️ 以下 URL 为临时签名 URL,有效期约 24 小时,请尽快下载或转存
for (const f of r.ResultFile3Ds) {
console.log(f.Type, '->', f.Url);
}
break;
}
if (r.Status === 'FAIL') {
console.error('FAIL:', r.ErrorCode, r.ErrorMessage);
break;
}
await new Promise(resolve => setTimeout(resolve, 8000));
}
}

main().catch(console.error);

2. 图生 3D(单图 / 多视角生成 3D 模型)

根据一张参考图生成完整 3D 模型,或多张不同角度的参考图获得最高还原度:
const { submitHunyuan3DTask } = require('./mps-api');

// 场景 A:图生 3D(完整资产 + PBR)
await submitHunyuan3DTask({
ImageUrl: 'https://example.com/test.png',
EnablePBR: true,
});

// 场景 B:图生 3D(仅几何,速度快)
await submitHunyuan3DTask({
ImageUrl: 'https://example.com/test.png',
GenerateType: 'Geometry',
FaceCount: 100000,
});

// 场景 C:多视角图生 3D(至少 2 张,必须包含 front 视角;质量要求高可追加 left / right)
await submitHunyuan3DTask({
MultiViewImages: [
{ ViewType: 'front', ViewImageUrl: 'https://example.com/front.png' },
{ ViewType: 'back', ViewImageUrl: 'https://example.com/back.png' },
],
EnablePBR: true,
});

// 场景 D:多视角图生几何
await submitHunyuan3DTask({
MultiViewImages: [
{ ViewType: 'front', ViewImageUrl: 'https://example.com/front.png' },
{ ViewType: 'back', ViewImageUrl: 'https://example.com/back.png' },
],
GenerateType: 'Geometry',
});

3. 带任务队列的生产级用法

在实际项目中,建议实现任务队列控制并发数,避免超过 API 频率限制:
const { submitHunyuan3DTask, queryHunyuan3DTask } = require('./mps-api');

/**
* 通用轮询函数:带超时与间隔控制
* @param {string} taskId 任务 ID
* @param {object} [options]
* @param {number} [options.timeoutMs=600000] 超时时间,默认 10 分钟
* @param {number} [options.intervalMs=8000] 轮询间隔,默认 8 秒(不要低于 1 秒,会触发限频)
* @returns {Promise<object>} DONE 状态的完整 Response
*/
async function pollTaskResult(taskId, options = {}) {
const { timeoutMs = 10 * 60 * 1000, intervalMs = 8000 } = options;
const deadline = Date.now() + timeoutMs;

while (Date.now() < deadline) {
const r = await queryHunyuan3DTask(taskId);
if (r.Status === 'DONE') return r;
if (r.Status === 'FAIL') {
throw new Error(`task failed: ${r.ErrorCode} - ${r.ErrorMessage}`);
}
await new Promise(resolve => setTimeout(resolve, intervalMs));
}
throw new Error(`poll timeout after ${timeoutMs} ms, TaskId: ${taskId}`);
}

/**
* 生产级工作流:先用 Geometry 模式快速验证骨架,满意后再生成完整资产
* (仅几何约 40s,完整资产约 120s,P50 参考值)
*/
async function generateWithPreview(prompt) {
// ① 先跑仅几何任务,快速评估模型骨架
const geometryTask = await submitHunyuan3DTask({
Prompt: prompt,
GenerateType: 'Geometry',
FaceCount: 200000,
});
const geometryResult = await pollTaskResult(geometryTask.TaskId);
console.log('几何预览完成,文件数:', geometryResult.ResultFile3Ds.length);

// ② 满意后再提交完整资产任务(几何 + 纹理 [+ PBR])
const finalTask = await submitHunyuan3DTask({
Prompt: prompt,
GenerateType: 'Normal',
FaceCount: 500000,
EnablePBR: true,
});
const finalResult = await pollTaskResult(finalTask.TaskId);

// ⚠️ 收到 DONE 后立即下载转存(URL 约 24 小时过期)
return finalResult.ResultFile3Ds; // OBJ / GLB 文件列表
}


配置文件参考

以下是一个完整的配置示例,涵盖图片和视频生成的所有可配置项:
{
"tencentCloud": {
"secretId": "TENCENTCLOUD_SECRET_ID",
"secretKey": "TENCENTCLOUD_SECRET_KEY",
"region": "ap-guangzhou"
},
"hunyuan3d": {
"generateType": "Normal",
"enablePBR": false,
"faceCount": 500000,
"multiView": {
"enabled": false,
"minViews": 2,
"maxViews": 8,
"requiredViewType": "front"
}
},
"concurrency": {
"maxConcurrentTasks": 1,
"pollIntervalSeconds": 8,
"pollTimeoutMinutes": 10
}
}

常见问题

创建任务报 InvalidParameter 错误?

错误码
说明
InvalidParameter.NoInputSpecified
Prompt / ImageUrl / MultiViewImages 三者都未传。
InvalidParameter.PromptImageConflict
Prompt 与 ImageUrl / MultiViewImages 同时提供。
InvalidParameter.MultiInputConflict
ImageUrl 与 MultiViewImages 同时提供。
InvalidParameter.MissingFrontView
MultiViewImages 未包含 front 视角。
InvalidParameter.InsufficientViews
MultiViewImages 数量少于2。
InvalidParameter.DuplicateViewType
出现重复的 ViewType。
InvalidParameter.FaceCountOutOfRange
FaceCount 不在 [3000, 1500000]。
InvalidParameter.PromptTooLong
Prompt 超过 1024 utf-8 字符。

创建任务报 AuthFailure 错误?

错误码
原因
AuthFailure.SignatureExpire
本机时间与腾讯云服务器偏差 > 5 分钟,请校准 NTP。
AuthFailure.SecretIdNotFound
SecretId 不存在或已删除。
AuthFailure.UnauthorizedOperation / UnauthorizedOperation
主账号 AppId 尚未在混元 3D 服务白名单内(联系商务开通),或子账号未绑定 CAM 策略 QcloudMPSFullAccess。

轮询一直返回 WAIT/RUN 状态?

完整 3D 资产(Normal)约180秒、仅几何(Geometry)约80秒(P50参考值),排队时间视平台负载而定,通常 < 10分钟。建议轮询超时设置为10分钟,间隔510秒;首次收到 Progress ≥ 90 后可加密到35秒,但不要低于1秒,会触发限频。

任务失败了会计费吗?

不会。仅 Query 首次返回 Status=DONE 时计费;未 DONE 的任务不计费,重复查询也不会重复计费。

Query 返回 ResourceNotFound.TaskId?

TaskId 在服务端保留7天,超期后自动清理。该错误走 HTTP 200,通过响应体的 ErrorCode / ErrorMessage 承载(响应中不含 Status 字段)。客户端判定顺序建议:先看 Response.ErrorCode 是否存在,存在即视为错误分支;否则再按 Response.Status 分派业务逻辑。

反馈问题需要提供什么?

RequestId(Submit 或 Query 响应里的 RequestId,非常关键)、TaskId(若有)、完整请求 Body(脱敏后)、期望结果 vs 实际结果的差异。

附录:HTTP 原始请求示例

如果您使用其他语言(Python / Go / Java 等),可以参考以下 HTTP 原始请求格式:

创建 3D 生成任务(文生 3D)

输入示例
curl -X POST https://mps.tencentcloudapi.com/ \\
-H "Authorization: TC3-HMAC-SHA256 Credential=AKIDxxxxxxxx/2026-08-30/mps/tc3_request, SignedHeaders=content-type;host, Signature=fe5f6f..." \\
-H "Content-Type: application/json" \\
-H "X-TC-Action: SubmitHunyuan3DTask" \\
-H "X-TC-Version: 2019-06-12" \\
-H "X-TC-Timestamp: 1756543200" \\
-H "X-TC-Region: ap-guangzhou" \\
-d '{
"Prompt": "a cute cartoon dinosaur, green, small horns",
"FaceCount": 500000
}'
输出示例
{
"Response": {
"TaskId": "r_44504e4b9a3b11f186b56a073b12405b",
"RequestId": "d344d00c-b131-45ec-8de9-829e0c427dca"
}
}

查询 3D 生成任务

输入示例
POST / HTTP/1.1
Host: mps.tencentcloudapi.com
Content-Type: application/json
X-TC-Action: QueryHunyuan3DTask
X-TC-Version: 2019-06-12

{
"TaskId": "r_44504e4b9a3b11f186b56a073b12405b"
}

输出示例-已完成
{
"Response": {
"Status": "DONE",
"Progress": 100,
"ResultFile3Ds": [
{
"Type": "GLB",
"Url": "https://hunyuan-3d-12583xxxx3.cos.ap-guangzhou.myqcloud.com/gen_tmp_test/<task_hash>/<file_hash>.glb?q-sign-algorithm=sha1&...",
"PreviewImageUrl": "https://hunyuan-base-prod-12583xxxx3.cos.ap-guangzhou.myqcloud.com/openapi/text2img/<preview_hash>.png?q-sign-algorithm=sha1&..."
},
{
"Type": "OBJ",
"Url": "https://hunyuan-3d-12583xxxx3.cos.ap-guangzhou.myqcloud.com/gen_tmp_test/<task_hash>/<file_hash>.obj?q-sign-algorithm=sha1&..."
},
{
"Type": "OBJ",
"Url": "https://hunyuan-3d-12583xxxx3.cos.ap-guangzhou.myqcloud.com/gen_tmp_test/<task_hash>/<file_hash>.zip?q-sign-algorithm=sha1&..."
}
],
"RequestId": "8189fa91-1c54-499c-8ce3-e182ec9c19ce"
}
}
输出示例-执行中
{
"Response": {
"Status": "RUN",
"Progress": 0,
"RequestId": "f3193547-4119-48d8-aa13-b27d29b49224"
}
}
输出示例-任务不存在或已过期
{
"Response": {
"ErrorCode": "ResourceNotFound.TaskId",
"ErrorMessage": "task not found or expired",
"RequestId": "0ba287dc-f6b3-4f93-bc3a-887e7f971f90"
}
}