---
title: "Imported and uploaded 3D models in the world"
description: "A creator brings their own character, vehicle, or prop mesh (a glb or gltf) and wants it in the scene. That is a model ASSET shown through a `RenderableComponent`. This is distinct from building geometry in-engine from primitives (see model-authoring-parametric-csg)."
engineVersion: v1.0.234
date: 2026-09-28
license: "(c) Gessa, proprietary. Cite with attribution to https://gessa.ai/docs/. Terms: https://gessa.ai/terms/."
canonical: https://gessa.ai/docs/knowledge/playbooks/imported-and-uploaded-models/
---

# Imported and uploaded 3D models in the world

## When to use

A creator brings their own character, vehicle, or prop mesh (a glb or gltf) and
wants it in the scene. That is a model ASSET shown through a
`RenderableComponent`. This is distinct from building geometry in-engine from
primitives (see model-authoring-parametric-csg).

## The recipe

1. Get the asset in: an uploaded or imported model becomes a project model asset.
   Create or register it with `project_create_asset` (`project.asset.create`), or
   pick one already in the catalog (see asset-acquisition-strategy). The SDK
   authoring path is `ProjectAuthoringHost.uploadAsset` for a file upload.
2. Show it on an entity: attach a `RenderableComponent`
   `{ "type":"RenderableComponent", "visible": true, "shape":"mesh",
   "assetId": <model asset id>, "renderSpace":"world" }`. `shape` MUST be `mesh`
   for a model asset; `box`/`sphere`/`capsule` are primitive shapes with no asset.
3. Materials: assign looks through `materialSlots` (or a `materialRef`) so the
   model uses your project materials (see materials-and-looks) instead of its
   embedded defaults.
4. Animate a rigged model: attach an `AnimationStateComponent` and play a clip by
   `clipKey` (see animation-clips-and-poses); the clip keys come from inside the
   model asset.
5. Give it presence: add a `ColliderComponent` sized to the model so it blocks or
   is hittable (the mesh render alone has no collision).

## Pitfalls

- `shape` must be `mesh` and `assetId` set to the model asset; a mesh renderable
  with no asset shows nothing, and a primitive shape ignores the asset.
- Importing a model is NOT a semantic-patch op; the asset comes in through the
  asset create or upload path, then the renderable references it.
- The render is a look, not a body; collision, triggers, and hits still need a
  `ColliderComponent` (see physics-colliders-rigidbodies).
- Animation clips are whatever the asset ships; a `clipKey` that the model does
  not contain plays nothing (see animation-clips-and-poses).

## Verify

- `qa_capture_renderer_viewport` (`qa.renderer.viewport.capture`) to confirm the
  model renders with its materials.
- `project_get_graph_snapshot` to confirm the `RenderableComponent` `shape:"mesh"`
  and `assetId` resolved.
