3D model generation
The polyGen step turns a text prompt or a reference image into a downloadable 3D model. Three engines are available, picked with the engine + model discriminator pair:
engine / model | Best for | Notes |
|---|---|---|
comfy / hunyuan3D | Image → 3D on Civitai's own workers | Tencent Hunyuan3D (open model, v2 / v2.1 / v2-mini). imageTo3D plus a shapeGen → texGen split. Lowest Buzz cost and the most knobs (steps, cfg, sampler, octree). Image-only; no rigging. |
fal / meshy | Text-to-3D, rigging & animation | Meshy, FAL-hosted, in two versions picked with version. v6 (default) does textTo3D and imageTo3D; v7 does imageTo3D and multiImageTo3D with an ultraMode fidelity tier, but has no text path. GLB + FBX + preview thumbnail, optionally a rigged, animation-ready character with walk/run clips. The only text-capable engine. |
fal / tripo | Fast hosted image → 3D with fine texture control | Tripo v2.5, FAL-hosted. imageTo3D only. GLB (or FBX with quad) + preview image. HD/PBR texturing and quad topology. |
Default choice for new integrations: for image-to-3D, lead with engine: "comfy", model: "hunyuan3D" — it runs on Civitai's own Comfy workers, costs the least, and exposes the most control. Reach for model: "meshy" when you need a text prompt, rigging, or animation (its only home), and model: "tripo" for fast hosted image-to-3D with quad topology or HD/PBR textures.
Every generation returns a GLB in the step's output.model. 3D generation runs for minutes, not seconds — always submit with wait=0 and either poll GetWorkflow or register a webhook (see Results & webhooks).
Prerequisites
- A Civitai orchestration token (Quick start → Prerequisites)
- For any
imageTo3Dcall: a publicly reachable source image URL (a Civitai CDN URL or your own hosted image)
Meshy — text-to-3D
Meshy's text path generates geometry and textures from a prompt alone. mode: "preview" returns untextured geometry fast for iteration; mode: "full" (default) adds textures.
POST https://orchestration.civitai.com/v2/consumer/workflows?wait=0
Authorization: Bearer <your-token>
Content-Type: application/json
{
"steps": [{
"$type": "polyGen",
"input": {
"engine": "fal",
"model": "meshy",
"operation": "textTo3D",
"prompt": "a low-poly viking helmet with engraved runes",
"mode": "full",
"topology": "triangle",
"targetPolycount": 30000
}
}]
}/v2/consumer/workflowsRequest body — edit to customize (e.g. swap the image URL or prompt)
Meshy — image-to-3D
Reconstruct a model from a single reference image. Set shouldTexture: false for a bare mesh.
POST https://orchestration.civitai.com/v2/consumer/workflows?wait=0
Authorization: Bearer <your-token>
Content-Type: application/json
{
"steps": [{
"$type": "polyGen",
"input": {
"engine": "fal",
"model": "meshy",
"operation": "imageTo3D",
"imageUrl": "https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/dd4b4ad5-040f-4f0e-baa3-6e1ff00add65/original=true,quality=90,optimized=true/26781018.jpeg",
"shouldTexture": true,
"topology": "quad",
"targetPolycount": 50000,
"enablePbr": true
}
}]
}/v2/consumer/workflowsRequest body — edit to customize (e.g. swap the image URL or prompt)
Rigging & animation (Meshy only)
Set enableRigging: true to get an armature-bound character plus basic walk/run clips; add enableAnimation: true for a full animated take. These populate the extra output blobs described in Reading the result. Works best on a full-body humanoid subject in an A-pose.
POST https://orchestration.civitai.com/v2/consumer/workflows?wait=0
Authorization: Bearer <your-token>
Content-Type: application/json
{
"steps": [{
"$type": "polyGen",
"input": {
"engine": "fal",
"model": "meshy",
"operation": "textTo3D",
"prompt": "a friendly cartoon wizard in robes, full body, A-pose",
"mode": "full",
"topology": "quad",
"targetPolycount": 60000,
"enablePbr": true,
"enableRigging": true
}
}]
}/v2/consumer/workflowsRequest body — edit to customize (e.g. swap the image URL or prompt)
Meshy v7 — image-to-3D
Meshy v7 is a newer generation of the same model. Opt in with version: "v7"; omit version and you stay on v6. It takes everything v6's imageTo3D takes, plus ultraMode for higher-fidelity geometry and modelType: "lowpoly" for a cleaner low-poly mesh. It has no text-to-3D path — textTo3D stays on v6.
POST https://orchestration.civitai.com/v2/consumer/workflows?wait=0
Authorization: Bearer <your-token>
Content-Type: application/json
{
"steps": [{
"$type": "polyGen",
"input": {
"engine": "fal",
"model": "meshy",
"version": "v7",
"operation": "imageTo3D",
"imageUrl": "https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/dd4b4ad5-040f-4f0e-baa3-6e1ff00add65/original=true,quality=90,optimized=true/26781018.jpeg",
"ultraMode": true,
"topology": "quad",
"targetPolycount": 50000,
"enablePbr": true
}
}]
}/v2/consumer/workflowsRequest body — edit to customize (e.g. swap the image URL or prompt)
Unlike v6, v7 prices per feature — a bare mesh is cheaper than a textured one, and ultraMode, rigging and animation each add to the bill. See Cost.
Meshy v7 — multi-image-to-3D
Give v7 up to four views of the same object and it reconstructs from all of them, which resolves geometry a single view can't. ultraMode and modelType aren't available on this operation; everything else matches imageTo3D.
POST https://orchestration.civitai.com/v2/consumer/workflows?wait=0
Authorization: Bearer <your-token>
Content-Type: application/json
{
"steps": [{
"$type": "polyGen",
"input": {
"engine": "fal",
"model": "meshy",
"version": "v7",
"operation": "multiImageTo3D",
"imageUrls": [
"https://example.com/front.png",
"https://example.com/side.png",
"https://example.com/back.png"
],
"topology": "quad",
"targetPolycount": 50000
}
}]
}/v2/consumer/workflowsRequest body — edit to customize (e.g. swap the image URL or prompt)
Meshy parameters
Shared by both versions unless noted:
| Field | Required | Default | Notes |
|---|---|---|---|
version | v6 | v6 or v7. Omit to stay on v6. | |
operation | ✅ | — | v6: textTo3D or imageTo3D. v7: imageTo3D or multiImageTo3D. |
prompt | textTo3D only | — | Max 600 chars. |
imageUrl | imageTo3D only | — | Public source image URL. |
mode | full | v6 textTo3D only. preview = untextured geometry (fast), full = textured. | |
enablePromptExpansion | false | v6 textTo3D only. Expands the prompt with an LLM before generation. | |
shouldTexture | true | Not on v6 textTo3D. false returns a bare mesh. | |
topology | triangle | triangle or quad. | |
targetPolycount | 30000 | Range 100–300000. | |
symmetryMode | auto | off, auto, or on. | |
shouldRemesh | true | Remesh to the target topology/polycount. | |
enablePbr | false | Generate PBR (metallic/roughness) texture maps. | |
texturePrompt | — | Optional text guidance for texturing (max 600 chars). | |
enableRigging | false | Produce a rigged character + basic walk/run animations. | |
enableAnimation | false | Produce an animated GLB/FBX. Requires enableRigging. | |
seed | random | v6 only. Reproducibility. Assigned automatically when omitted. |
v7 adds:
| Field | Required | Default | Notes |
|---|---|---|---|
imageUrls | multiImageTo3D only | — | 1–4 public URLs, all showing the same object from different angles. |
ultraMode | false | imageTo3D only. Higher-fidelity geometry with finer surface detail. | |
modelType | standard | imageTo3D only. lowpoly produces cleaner low-poly geometry and makes Meshy ignore topology, targetPolycount and shouldRemesh. | |
poseMode | none | none, a-pose, or t-pose. | |
textureImageUrl | — | Reference image guiding the texturing pass. | |
riggingHeightMeters | 1.7 | Approximate character height. Only used with enableRigging. | |
animationActionId | 92 | Meshy animation preset, 0–696 (0 is "Idle"). Only used with enableAnimation. See Meshy's animation library. |
Tripo — image-to-3D
Rolling out
Tripo v2.5 is newly added. The interactive runner below works once it's live in production; until then it returns a 400 for discriminator value tripo.
Tripo reconstructs a model from a single image with fine control over texturing. texture picks the fidelity (no/standard/HD); pbr adds PBR maps; quad switches the mesh to quad topology (and produces FBX instead of GLB).
POST https://orchestration.civitai.com/v2/consumer/workflows?wait=0
Authorization: Bearer <your-token>
Content-Type: application/json
{
"steps": [{
"$type": "polyGen",
"input": {
"engine": "fal",
"model": "tripo",
"imageUrl": "https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/dd4b4ad5-040f-4f0e-baa3-6e1ff00add65/original=true,quality=90,optimized=true/26781018.jpeg",
"texture": "HD",
"pbr": true,
"orientation": "align_image"
}
}]
}/v2/consumer/workflowsRequest body — edit to customize (e.g. swap the image URL or prompt)
Quad topology yields cleaner edge loops for downstream editing. Because Tripo emits FBX (not GLB) in quad mode, read the result from output.fbxModel rather than output.model:
POST https://orchestration.civitai.com/v2/consumer/workflows?wait=0
Authorization: Bearer <your-token>
Content-Type: application/json
{
"steps": [{
"$type": "polyGen",
"input": {
"engine": "fal",
"model": "tripo",
"imageUrl": "https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/dd4b4ad5-040f-4f0e-baa3-6e1ff00add65/original=true,quality=90,optimized=true/26781018.jpeg",
"texture": "standard",
"quad": true,
"autoSize": true
}
}]
}/v2/consumer/workflowsRequest body — edit to customize (e.g. swap the image URL or prompt)
Tripo parameters
| Field | Required | Default | Notes |
|---|---|---|---|
imageUrl | ✅ | — | Public source image URL. |
texture | standard | no (mesh only), standard, or HD. | |
pbr | false | Generate PBR maps. Implies a textured result even when texture: "no". | |
faceLimit | adaptive | Cap the output face count. Range 1000–500000. | |
autoSize | false | Scale the model to real-world dimensions (metres). | |
quad | false | Quad topology. Produces an FBX mesh instead of GLB (read output.fbxModel). | |
textureAlignment | original_image | original_image or geometry. | |
orientation | default | align_image auto-rotates the model to match the input image. | |
seed | random | Geometry reproducibility. Assigned automatically when omitted. | |
textureSeed | random | Texture reproducibility. |
Hunyuan3D — image-to-3D
Tencent's open Hunyuan3D running on Civitai's own Comfy workers — the cheapest 3D path and the one with the most control. Image-only. The default imageTo3D operation generates the mesh and (when shouldTexture is true) textures it in one submission. Pick fidelity with modelVersion:
modelVersion | Notes |
|---|---|
v2 | Default. Fast — 5 steps, 3072 shape resolution. |
v2.1 | Highest quality — 30 steps, 4096 shape resolution. |
v2-mini | Smallest/fastest variant, same defaults as v2. |
POST https://orchestration.civitai.com/v2/consumer/workflows?wait=0
Authorization: Bearer <your-token>
Content-Type: application/json
{
"steps": [{
"$type": "polyGen",
"input": {
"engine": "comfy",
"model": "hunyuan3D",
"operation": "imageTo3D",
"modelVersion": "v2.1",
"imageUrl": "https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/dd4b4ad5-040f-4f0e-baa3-6e1ff00add65/original=true,quality=90,optimized=true/26781018.jpeg",
"shouldTexture": true,
"octreeResolution": 256
}
}]
}/v2/consumer/workflowsRequest body — edit to customize (e.g. swap the image URL or prompt)
v2-mini is the quickest way to preview a mesh:
/v2/consumer/workflowsRequest body — edit to customize (e.g. swap the image URL or prompt)
Split shapeGen / texGen (advanced)
The imageTo3D operation runs shape then texture internally. To cache or reuse an untextured mesh — or to re-texture one mesh several times — run the two operations as separate steps and reference the shape output from the texture step. mesh takes a step $ref to the shape step's GLB:
POST https://orchestration.civitai.com/v2/consumer/workflows?wait=0
Authorization: Bearer <your-token>
Content-Type: application/json
{
"steps": [
{
"$type": "polyGen",
"name": "shape",
"input": {
"engine": "comfy",
"model": "hunyuan3D",
"operation": "shapeGen",
"modelVersion": "v2.1",
"imageUrl": "https://.../reference.jpg"
}
},
{
"$type": "polyGen",
"name": "texture",
"input": {
"engine": "comfy",
"model": "hunyuan3D",
"operation": "texGen",
"modelVersion": "v2.1",
"imageUrl": "https://.../reference.jpg",
"mesh": { "$ref": "shape", "path": "output.model.url" },
"enablePbr": true
}
}
]
}Hunyuan3D parameters
| Field | Required | Default | Notes |
|---|---|---|---|
operation | imageTo3D | imageTo3D (mesh + texture), shapeGen (mesh only), or texGen (texture an existing mesh). | |
modelVersion | v2 | v2, v2.1, or v2-mini. | |
imageUrl | ✅ | — | Public source image URL. |
prompt | — | Optional guidance for imageTo3D/shapeGen (max 600 chars). | |
mesh | texGen only | — | AIR or step $ref to the mesh to texture. |
shouldTexture | true | imageTo3D only. false returns a bare mesh (and bills as shape-only). | |
shouldRemesh | false | imageTo3D/texGen. Remesh before texturing. | |
enablePbr | true | imageTo3D/texGen. Generate PBR maps. | |
steps | 5 (v2/v2-mini), 30 (v2.1) | Range 1–150. Scales cost linearly (see below). | |
cfgScale | 5 (v2/v2-mini), 7.5 (v2.1) | Range 0–30. | |
octreeResolution | 256 | Range 16–512. Higher = finer mesh; scales cost linearly. | |
resolution | 3072 (v2/v2-mini), 4096 (v2.1) | Shape resolution. Range 1–8192. | |
sampler | euler | ComfyUI sampler (e.g. dpmpp_2m, uni_pc). | |
scheduler | normal | normal, karras, exponential, sgm_uniform, simple, ddim_uniform, beta. | |
vaeNumChunks | 8000 | Range 1000–500000. VAE decode chunking. | |
meshThreshold | 0.6 | Range 0–1. Surface extraction threshold. | |
shift | 1 | Timestep shift. | |
modelAir | version default | Override the model checkpoint AIR (urn:air:hy3d:repository:huggingface:...). | |
seed | random | Assigned automatically when omitted. |
Reading the result
A succeeded polyGen step carries the model blobs in output. The required model is always a GLB; the other blobs appear only when the engine produced them (FBX, thumbnail, and Meshy's rigging/animation outputs).
{
"status": "succeeded",
"steps": [{
"name": "0",
"$type": "polyGen",
"status": "succeeded",
"output": {
"model": { "id": "blob_abc.glb", "available": true, "url": "https://.../signed.glb", "format": "glb" },
"fbxModel": { "id": "blob_abc.fbx", "available": true, "url": "https://.../signed.fbx", "format": "fbx" },
"thumbnail": { "id": "blob_abc-thumbnail.png", "available": true, "url": "https://.../signed.png" }
}
}]
}Fields:
model— the generated model in GLB format (always present). For Tripoquadruns the GLB is empty (available: false) and the mesh lands infbxModelinstead.fbxModel— FBX export, when the engine produced one.thumbnail— preview image of the model, when available.riggedModel/riggedFbxModel— Meshy rigging output (enableRigging: true).animatedModel/animatedFbxModel— Meshy animation output (enableAnimation: true).basicAnimations— Meshy walk/run clips (walkingModel,runningModel, …) bundled when rigging is enabled.
Hunyuan3D populates model only (the textured GLB) — no FBX or thumbnail.
Blob URLs are signed and expire — refetch the workflow or call GetBlob for a fresh URL.
Runtime
3D generation is minutes-scale, so a single long-poll won't cover it — submit with wait=0 and poll GetWorkflow (or use a webhook). Meshy holds its worker claim for up to 20 minutes; textured and rigged runs sit at the higher end of that. Tripo is typically faster, but as a fresh release treat its timings as preliminary until fleet capacity settles. Hunyuan3D is compute-intensive and depends on Comfy GPU worker availability — it can queue before it runs, and v2.1 at high octreeResolution/steps is the slowest path; v2 and v2-mini are the quickest.
Cost
Billed in Buzz on the workflow's transactions. Use whatif=true for an exact preview; see Payments (Buzz) for currency selection.
Meshy v6 is a flat rate — rigging, animation, PBR, topology, and polycount don't change the price:
| Shape | Buzz |
|---|---|
Any v6 textTo3D or imageTo3D run | 1040 |
Meshy v7 prices per feature instead. Start from the base mesh and add each option you enable:
buzz = 1040 base mesh
+ 520 if shouldTexture (default on)
+ 260 if ultraMode (imageTo3D only)
+ 260 if enableRigging
+ 156 if enableAnimation| Shape | Buzz |
|---|---|
shouldTexture: false (bare mesh) | 1040 |
| textured (default) | 1560 |
textured + ultraMode | 1820 |
| textured + rigged | 1820 |
textured + ultraMode + rigged + animated | 2236 |
multiImageTo3D uses the same schedule minus ultraMode, and the number of input images doesn't change the price. topology, targetPolycount, symmetryMode, enablePbr, poseMode and modelType are all free.
Tripo is driven by texture fidelity plus the quad surcharge:
buzz = (textureDollars + (quad ? 0.05 : 0)) × 1000 × 1.3
textureDollars = 0.2 (no) | 0.3 (standard, or "no" with pbr) | 0.4 (HD)| Shape | Buzz |
|---|---|
texture: "standard" (default) | 390 |
texture: "no" (mesh only) | 260 |
texture: "HD" | 520 |
+ quad (any texture) | +65 |
texture: "HD" + quad | 585 |
faceLimit, autoSize, orientation, textureAlignment, and both seeds don't affect Tripo's price.
Hunyuan3D bills a base shape charge scaled by mesh resolution and step count, plus a flat texturing charge when a texture is produced:
shape = 60 × (octreeResolution / 256) × (steps / defaultSteps)
texGen = 100 (added when texturing; the whole cost for the texGen operation)
defaultSteps = 30 (v2.1), 5 (v2 / v2-mini)| Shape | Buzz |
|---|---|
imageTo3D, textured, defaults | 160 |
imageTo3D, shouldTexture: false (mesh only) | 60 |
shapeGen only | 60 |
texGen only | 100 |
imageTo3D textured, octreeResolution: 512 | 220 |
modelVersion shifts the step baseline but not the price at defaults (each version's default steps normalises the steps factor to 1). Doubling octreeResolution or steps doubles the shape charge; the texGen charge is flat.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
400 — "No derived type found for discriminator value 'tripo'" | Tripo isn't live in your target environment yet | Use model: "meshy", or wait for the Tripo rollout. |
400 — "Prompt is required" / "ImageUrl is required" | operation/model doesn't match the field you sent | textTo3D needs prompt; every imageTo3D and all Tripo calls need imageUrl. |
400 — "No derived type found for discriminator value 'textTo3D'" | version: "v7" with a text prompt | v7 has no text path. Drop version to use v6, or switch to imageTo3D. |
400 — "enableAnimation requires enableRigging" | v7 animation without an armature | Set enableRigging: true as well; Meshy animates the rigged character. |
400 — "multiImageTo3D requires between one and four source images" | imageUrls empty or longer than 4 | Send 1–4 views of the same object. |
v7 lowpoly ignores your polycount | modelType: "lowpoly" overrides the remesh controls | Expected — use modelType: "standard" if you need targetPolycount/topology honoured. |
output.model.available is false | Tripo quad run (mesh went to FBX), or the source image was rejected | Read output.fbxModel for quad runs; otherwise check the source image is reachable. |
Hunyuan3D step sits unassigned / queued | No free Comfy worker holds the model | Wait for capacity, or fall back to hosted model: "meshy" / "tripo". |
Request timed out (wait expired) | 3D generation exceeds the long-poll window | Submit with wait=0 and poll, or register a webhook. |
Step failed, reason = "blocked" | Content moderation | Don't retry the same input — see Errors & retries → Step-level failures. |
Related
InvokePolyGenStepTemplate— the per-recipe endpointSubmitWorkflow— generic path for chainingGetWorkflow— for pollingGetBlob— refetch an expired model/thumbnail URL- Results & webhooks — handling long-running workflows
- Full parameter catalog: the
PolyGenInputschema in the API reference - Endpoint OpenAPI spec — standalone OpenAPI 3.1 YAML for this endpoint