3D Models

This tutorial will teach you how to convert, load, and use 3D Models in Cesium via the Primitive API. If you’re new to Cesium, you might want to check out the 3D Models section of the Visualizing Spatial Data tutorial instead.

Cesium supports 3D models, including key-frame animation, skinning, and individual node picking, using glTF, an emerging industry-standard format for 3D models on the web by the Khronos Group, the consortium behind WebGL and COLLADA. Cesium ion also provides a solution to convert COLLADA models to glTF for optimized streaming into CesiumJS apps.

Quick start

Cesium includes a few ready-to-use binary glTF models:

  • An aircraft with animated propellers
  • A ground vehicle with animated wheels
  • A character with a skinned walk cycle
  • A hot air balloon
  • A milk truck (Draco-compressed milk truck also included)

Aircraft Model Vehicle Model Character Model Milk Truck Model

These models each have their own directory in Apps/SampleData/models. Most will include the original COLLADA file (.dae), a glTF file (.gltf) and/or a binary glTF file (.glb). The original COLLADA file is not needed for use in Cesium apps.

Let’s write code to load these models. Open the Hello World example in Sandcastle. Under var viewer = ... on Line 4, add a scene variable.

Copy to clipboard. Data copied clipboard.
var scene = viewer.scene;

Next, load the ground vehicle model using Cesium.Model.fromGltf by adding the following code.

Copy to clipboard. Data copied clipboard.
var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
    Cesium.Cartesian3.fromDegrees(-75.62898254394531, 40.02804946899414, 0.0));
var model = scene.primitives.add(Cesium.Model.fromGltf({
    url : '../../../../Apps/SampleData/models/GroundVehicle/GroundVehicle.glb',
    modelMatrix : modelMatrix,
    scale : 200.0

Hit F8, then use the geocoder tool in the upper right to zoom to Exton, PA.


We are now looking straight down at the ground vehicle. We can zoom in closer with right-mouse drag and tilt the view with middle-mouse drag.

Zoomed in

Cesium.Model.fromGltf asynchronously loads the glTF model, including any external files, and renders it once it is completely loaded, which resolves the readyPromise. Just the url to the .gltf file is required, which is ../../../../Apps/SampleData/models/GroundVehicle/GroundVehicle.glb in this example.

An optional scale is also provided to fromGltf to enlarge the model. Many true-scale models can be small, so it can help to use a large scale when first testing a model, even something very large like 200000.0. For example:

Scaled model

A modelMatrix is also provided to fromGltf to position and rotate the model. This creates a local coordinate system for the model. Here, Cesium.Transforms.eastNorthUpToFixedFrame is used to create a local east-north-up coordinate system with an origin of -75.62898254394531 degrees longitude and 40.02804946899414 degrees latitude. The model’s modelMatrix property can be changed at any time to move the model.

To visualize the coordinate system, use the Cesium Inspector by adding the following line of code anywhere under var viewer = ... on Line 4.

Copy to clipboard. Data copied clipboard.

Hi F8 and now the inspector UI is shown in the upper left. Expand Primitives, click Pick a Primitive, click on the ground vehicle model, and then check show reference frame.

Reference Frame

Here, the x axis (east) is red, the y axis (north) is green, and z (up) is blue.

We can use the same code to load the aircraft or character model by just changing the url passed to fromGltf to '../../../../Apps/SampleData/models/CesiumAir/Cesium_Air.glb' or '../../../../Apps/SampleData/models/CesiumMan/Cesium_Man.glb', respectively. See the reference documentation for Cesium.Model.fromGltf for all its options.


Each of these models have animations built into them that were key-framed by an artist, i.e., an artist created an animation by defining several key poses, which Cesium interpolates at runtime to create a smooth animation.

To play the animations, add the following code after calling Cesium.Model.fromGltf.

Copy to clipboard. Data copied clipboard.
Cesium.when(model.readyPromise).then(function(model) {
        loop : Cesium.ModelAnimationLoop.REPEAT

Since animations are stored in the glTF model, we need to wait for the readyPromise to resolve before accessing them. addAll is used to play all animations in the model. Cesium.ModelAnimationLoop.REPEAT loops the animation until it is removed from the activeAnimations collection. To play a particular animation, use add instead, and provide the animation’s id (glTF JSON property name).

In addition to the loop option, addAll and add provide a number of options to control when the animation starts and stops, its speed, and its direction. For example, the following animates at half-speed (relative to the Cesium clock) and in reverse.

Copy to clipboard. Data copied clipboard.
    loop : Cesium.ModelAnimationLoop.REPEAT,
    speedup : 0.5,
    reverse : true

add returns a ModelAnimation object (addAll returns an array of these), which has events for when the animation starts, stops, and updates each frame. This allows, for example, starting one animation relative to another. See the start, stop, and update events.

Animation is synced with the Cesium clock, so to view them press play on the playback widget. You can increase, decrease and reverse the speed of the animations using the timeline and playback widgets.


To configure your app to automatically play animations, initialize the Viewer like this:

Copy to clipboard. Data copied clipboard.
var viewer = new Cesium.Viewer('cesiumContainer', {
    shouldAnimate : true


Like all Cesium primitives, Scene.pick will return a Model as part of its result if a model is selected. In addition, the glTF id (JSON property name) for the glTF node and glTF mesh are also returned, which allows precise picking of different model parts. The following example displays node and mesh name under the mouse cursor in the console window.

Copy to clipboard. Data copied clipboard.
var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
    function (movement) {
        var pick = scene.pick(movement.endPosition);
        if (Cesium.defined(pick) && Cesium.defined(pick.node) && Cesium.defined(pick.mesh)) {
            console.log('node: ' + pick.node.name + '. mesh: ' + pick.mesh.name);

Converting COLLADA to glTF

To convert a COLLADA model to glTF for use with Cesium, use the hosted model converter converter on Cesium ion, or see the COLLADA2GLTF converter provided by the Khronos Group.


If there is an issue loading a 3D model in Cesium, first pinpoint where the problem is. It will be either in

  • the COLLADA exporter of the modeling tool, e.g., Maya, Modo, SketchUp, etc., or
  • the COLLADA-to-glTF converter, or
  • the Cesium glTF renderer.

Troubleshooting on Mac

On Mac, to determine if a COLLADA file was exported correctly, double-click on the .dae file and it should appear in the Preview window. If the model has animations, mousing over the bottom of the window will bring up a toolbar to play them.

Mac preview

If the COLLADA file is not valid, Preview will display an error. This usually indicates that there is a bug in the COLLADA exporter used to create the COLLADA file.

Mac error

To try to workaround this, install Xcode, then right-click on the .dae file and select Open With -> Xcode.

Open with Xcode

Xcode displays the model similar to Preview but has more features like the ability to select individual nodes. Xcode also implements many workarounds for invalid COLLADA files so it can often load a COLLADA file that Preview can’t. If the model loads in Xcode, select File - Save to save the model with the workarounds, and then it should load in Preview OK.

Show in Xcode

If it still doesn’t load in Preview, then there is a problem with the COLLADA exporter. Make sure you have the latest version of the modeling tool and try the tips in this article. If it still doesn’t work, submit a bug to the modeling tool (not Cesium). It can also be worth trying exporting as .fbx or another format and then import into another modeling tool with a better COLLADA exporter.

Troubleshooting on Windows

On Windows, Visual Studio 2013 (including the free Community Edition) has a Model Editor that can load COLLADA models. To determine if a COLLADA file was exported correctly, drag and drop the .dae file onto Visual Studio and it should load. If it doesn’t, this usually indicates a bug in the COLLADA exporter used to create the COLLADA file. Make sure you have the latest version of the modeling tool and try the tips in this article. If it still doesn’t work, submit a bug to the modeling tool (not Cesium). It can also be worth trying exporting as .fbx or another format and then import into another modeling tool with a better COLLADA exporter.

Visual Studio

If you do not have Visual Studio, Autodesk has a WebGL viewer that allows drag-and-drop and does not require a login. The viewer doesn’t support animations. If the model has images, upload a zip with the .dae and image files.

Troubleshooting Cesium

Once we have a valid COLLADA file, upload it to Cesium ion to convert it to glTF, and then try to load it in Cesium. If it doesn’t load in Cesium or it displays incorrectly, there is either a bug in the converter or in Cesium. To get more details, open the browser’s developer tools (Ctrl-Shift-I in Chrome) and enable Pause on all exceptions (in the Sources tab in Chrome), and then reload the Cesium app.

Pause On All Exceptions

Post a message to the Cesium forum and we can often provide a workaround until a fix is available. In your post, please include:

  • The original COLLADA and converted glTF files. We recognize that not everyone can share their models, but if you can, it dramatically increases our ability to help.
  • The browser’s console window and any exceptions that were thrown when the model was loaded, e.g.



Check out the 3D models example in Sandcastle and the reference documentation for Model and ModelAnimationCollection.