面向 AI 助手:本页的 Markdown 版本位于 https://ark.volcengine.com/region:cn-beijing/docs/3d-generation.md,全部文档索引见 https://ark.volcengine.com/llms.txt。

3D 生成

3D 生成模型具备出色的三维内容生成能力,能够根据用户输入的图像,快速生成具备多边形面片与 PBR 材质的高精度 3D 资产。通过这篇教程您可以学习到如何调用豆包 3D 生成模型 API 来生成 3D 文件。

模型及API#

模型 ID(Model ID) 模型能力 产物规格 限流 API
doubao-seed3d-2-0-260328 图生3D
  • 生成带纹理和 PBR 材质的3D文件
产物面数
  • 100000 面
  • 500000 面
  • 1000000面产物格式

glb 、obj、usd、usdz
最大 RPM:300
最大并发:5
3D生成 API
hyper3d-gen2-260112 文生3D、图生3D
  • 生成带纹理和 PBR 材质的 3D 文件
产物面数
  • 三角面模型:[500, 1,000,000]
  • 四边面模型:[1,000, 200,000]产物格式
  • glb, obj, stl, fbx, usdz
最大 RPM: 60
最大并发: 3
影眸 API
hitem3d-2-0-251223 图生3D
  • 标准白膜
  • 标准纹理模型
  • 高精白膜
  • 高精纹理模型
产物面数
  • [100000, 2000000]产物格式
  • glb, obj, stl, fbx, usdz产物分辨率
  • 1536、1536 pro
最大 RPM: 600
最大并发: 30
数美 API

模型价格#

请参见:3D生成模型

使用流程#

3D 生成任务为异步任务。

  1. 通过 创建任务接口 创建3D生成任务,获得 任务 ID 。
  2. 通过 任务查询接口 + 任务 ID 查询任务状态,直到任务完成时,获取返回的 3D 产物下载链接,下载生成结果。

体验&调试#

可在 API Explorer,0代码体验通过 API 调用 3D 模型。支持灵活调整参数(如控制输出产物格式等),方便您直观感受模型实际使用过程。

代码调用#

效果预览#

输入 输出预览

上图为效果展示。实际产物为3D文件,类似 文件。

示例代码#

Python
import os
import time
# Install SDK:  python -m pip install --upgrade arkruntime
from arkruntime import Ark

# 初始化Ark客户端
client = Ark(
    # The base URL for model invocation .
    base_url="https://ark.cn-beijing.volces.com/api/v3",
    # Get API Key: https://ark.volcengine.com/region:cn-beijing/apikey
    api_key=os.getenv('ARK_API_KEY'),
)

print("----- create request -----")
# 创建3D生成任务
create_result = client.content_generation.tasks.create(
    # Replace with Model ID .
    model="doubao-seed3d-2-0-260328",
    content=[
        {
            # 参数
            "type": "text",
            "text": "--subdivisionlevel medium --fileformat glb"
        },
        {
            # 图片URL
            "type": "image_url",
            "image_url": {
                "url": "https://arkdocs.tos-cn-beijing.volces.com/images/domain-models/seed3d_imageTo3d.png"
            }
        }
    ]
)
print(create_result)

# 轮询查询部分
print("----- polling task status -----")
task_id = create_result.id
max_attempts = 60
for attempt in range(1, max_attempts + 1):
    get_result = client.content_generation.tasks.get(task_id=task_id)
    status = get_result.status
    if status == "succeeded":
        print("----- task succeeded -----")
        print(get_result)
        break
    elif status == "failed":
        print("----- task failed -----")
        print(f"Error: {get_result.error}")
        break
    if attempt == max_attempts:
        raise TimeoutError(f"Task {task_id} did not finish after {max_attempts} attempts")
    print(f"Current status: {status}, retrying after 60 seconds...")
    time.sleep(60)
  1. 创建3D生成任务,获取 3D 生成任务 ID。
Bash
curl -X POST https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ARK_API_KEY" \
  -d '{
    "model": "doubao-seed3d-2-0-260328",
    "content": [
        {
            "type": "text",
            "text": "--subdivisionlevel medium --fileformat glb"
        },
        {
            "type": "image_url",
            "image_url": {
                "url": "https://arkdocs.tos-cn-beijing.volces.com/images/domain-models/seed3d_imageTo3d.png"
            }
        }
    ]
}'
  1. 查询 3D 生成任务状态,直至任务状态为Success,返回产物下载链接。

替换 <TASK_ID> 为你的任务 ID。

Bash
curl -X GET https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks/<TASK_ID> \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ARK_API_KEY"
Go
package main

import (
    "context"
    "fmt"
    "os"
    "time"
    "github.com/volcengine/ark-runtime-go/arkruntime"
    model "github.com/volcengine/ark-runtime-go/arkruntime/model/contentgeneration"
)

func main() {
    // 请确保您已将 API Key 存储在环境变量 ARK_API_KEY 中
    // 初始化Ark客户端,从环境变量中读取您的API Key
    client := arkruntime.NewClientWithApiKey(
            // 从环境变量中获取您的 API Key。此为默认方式,您可根据需要进行修改
            os.Getenv("ARK_API_KEY"),
            // The base URL for model invocation .
            arkruntime.WithBaseUrl("https://ark.cn-beijing.volces.com/api/v3"),
    )
    ctx := context.Background()

    // Replace with Model ID .
    modelEp := "doubao-seed3d-2-0-260328"

    // 创建任务
    fmt.Println("----- create request -----")
    createReq := &model.CreateContentGenerationTaskRequest{
        Model: modelEp,
        Content: []model.ContentItem{
            {
                Type: model.ContentTypeText,
                Text: model.NewOptString("--subdivisionlevel medium --fileformat glb"),
            },
            {
                Type: model.ContentTypeImageURL,
                ImageURL: model.NewOptImageURL(model.ImageURL{
                        URL: "https://arkdocs.tos-cn-beijing.volces.com/images/domain-models/seed3d_imageTo3d.png",
                        }),
                },
        },
    }
    createResp, err := client.CreateContentGenerationTask(ctx, createReq)
    if err != nil {
        fmt.Printf("create content generation error: %v", err)
        return
    }
    taskID := createResp.ID
    fmt.Printf("Task Created with ID: %s", taskID)

    // 轮询查询部分
    fmt.Println("----- polling task status -----")
    const maxAttempts = 60
    for attempt := 1; attempt <= maxAttempts; attempt++ {
        getReq := taskID
        getResp, err := client.GetContentGenerationTask(ctx, getReq)
        if err != nil {
            fmt.Printf("get content generation task error: %v", err)
            return
        }

        status := getResp.Status
        if status == "succeeded" {
            fmt.Println("----- task succeeded -----")
            fmt.Printf("Task ID: %s", getResp.ID)
            fmt.Printf("Model: %s", getResp.Model)
            fmt.Printf("File URL: %s", getResp.Content.Or(model.TaskContent{}).FileURL.Or(""))
            fmt.Printf("Completion Tokens: %d", getResp.Usage.Or(model.TaskUsage{}).CompletionTokens)
            fmt.Printf("Created At: %d, Updated At: %d", getResp.CreatedAt.Or(0), getResp.UpdatedAt.Or(0))
            return
        } else if status == "failed" {
            fmt.Println("----- task failed -----")
            if getResp.Error.IsSet() {
                fmt.Printf("Error Code: %s, Message: %s", getResp.Error.Value.Code, getResp.Error.Value.Message)
            }
            return
        } else if attempt == maxAttempts {
            fmt.Printf("Task %s did not finish after %d attempts", taskID, maxAttempts)
            return
        } else {
            fmt.Printf("Current status: %s, retrying in 60 seconds...", status)
            time.Sleep(60 * time.Second)
        }
    }
}
Java
package com.volcengine.ark.runtime;

import com.volcengine.ark.runtime.models.content_generation.*;
import com.volcengine.ark.runtime.service.ArkService;
import okhttp3.ConnectionPool;
import okhttp3.Dispatcher;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;


public class ContentGenerationTaskExample {
    // 请确保您已将 API Key 存储在环境变量 ARK_API_KEY 中
    // 初始化Ark客户端,从环境变量中读取您的API Key
    static String apiKey = System.getenv("ARK_API_KEY");
    static ConnectionPool connectionPool = new ConnectionPool(5, 1, TimeUnit.SECONDS);
    static Dispatcher dispatcher = new Dispatcher();
    static ArkService service = ArkService.builder()
           .dispatcher(dispatcher)
           .connectionPool(connectionPool)
           .apiKey(apiKey)
           .baseUrl("https://ark.cn-beijing.volces.com/api/v3")
           // The base URL for model invocation .
           .build();
    public static void main(String[] args) {
        //Replace with Model ID .
        String model = "doubao-seed3d-2-0-260328";

        System.out.println("----- CREATE Task Request -----");
        List<ContentItem> contents = new ArrayList<>();

        // 参数
        contents.add(ContentItem.builder()
                .type(ContentType.TEXT)
                .text("--subdivisionlevel medium --fileformat glb")
                .build());

        // 图片URL
        contents.add(ContentItem.builder()
                .type(ContentType.IMAGE_URL)
                .imageUrl(ImageURL.builder()
                        .url("https://arkdocs.tos-cn-beijing.volces.com/images/domain-models/seed3d_imageTo3d.png")
                        .build())
                .build());

        // 创建3D生成任务
        CreateContentGenerationTaskRequest createRequest = CreateContentGenerationTaskRequest.builder()
                .model(model)
                .content(contents)
                .build();

        CreateContentGenerationTaskResponse createResult = service.createContentGenerationTask(createRequest);
        System.out.println(createResult);

        System.out.println("----- GET Task Request -----");

        // 获取任务详情
        String getRequest = createResult.getId();

        ContentGenerationTask getResult = service.getContentGenerationTask(getRequest);
        System.out.println(getResult);

        System.out.println("----- LIST Task Request -----");

        // 轮询查询部分
        System.out.println("----- polling task status -----");
        final int maxAttempts = 60;
        for (int attempt = 1; attempt <= maxAttempts; attempt++) {
            try {
                ContentGenerationTask getResponse = service.getContentGenerationTask(getRequest);
                String status = getResponse.getStatus().toString();
                if ("succeeded".equalsIgnoreCase(status)) {
                    System.out.println("----- task succeeded -----");
                    System.out.println(getResponse);
                    break;
                } else if ("failed".equalsIgnoreCase(status)) {
                    System.out.println("----- task failed -----");
                    System.out.println("Error: " + getResponse.getStatus());
                    break;
                } else if (attempt == maxAttempts) {
                    throw new IllegalStateException(
                            "Task " + getRequest + " did not finish after " + maxAttempts + " attempts");
                } else {
                    System.out.printf("Current status: %s, retrying in 60 seconds...", status);
                    TimeUnit.SECONDS.sleep(60);
                }
            } catch (InterruptedException ie) {
                Thread.currentThread().interrupt();
                System.err.println("Polling interrupted");
                break;
            }
        }
    }
}

其他说明#

控制产物参数#

通过--[parameters]的方式,控制3D文件输出的规格,包括产物面的数量、输出文格式等。

Bash
# 指定生成的3D文件的多边形面的数量为 100000 面,生成的3D文件格式为 glb
"content": [
        {
            "type": "text",
            "text": "--subdivisionlevel medium --fileformat glb"
        }
    ]

链接有效期#

任务数据(如任务状态、URL等)仅保留24小时,超时后会被自动清除。请您务必及时保存生成的文件。

限流说明#

同一主账号下,使用同一模型(不区分版本)的请求受到以下限制。超过对应限制会返回 “429: 'Too Many Requests'” 错误。

模型维度的限流#

不同模型的 RPM 和最大并发任务数不同,详见 3D生成能力。

  • RPM(Requests Per Minute):每分钟允许创建的 3D 生成任务数上限。超过上限时,创建任务请求将因触发限流而失败。
  • 最大并发任务数:同一时刻可处于处理状态的任务数上限。达到上限后,新创建的任务将进入队列等待处理。

非推理 API 请求频率限制#

  • QPS(Queries Per Second):每秒允许的请求数上限。超过上限时,任务请求将因触发限流而失败。

接口名称 账号维度的 QPS 上限
查询 3D 生成任务 20
查询 3D 生成任务列表 1
取消或删除 3D 生成任务 20