# Display a large number of GLB models

**URL:** <https://community.cesium.com/t/display-a-large-number-of-glb-models/34579>\
**Category:** CesiumJS\
**Created:** [August 16, 2024, 9:52pm UTC](https://community.cesium.com/t/display-a-large-number-of-glb-models/34579 "2024-08-16T21:52:08Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![adcomere](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/adcomere/32/14037_2.png) [@adcomere](https://community.cesium.com/u/adcomere)\
**Post date:** [August 16, 2024, 9:52pm UTC](https://community.cesium.com/t/display-a-large-number-of-glb-models/34579/1 "2024-08-16T21:52:08Z")

</div>

I have a scene where I need to display a FAIRLY large (~250) of simple 3D models.

The GLB file contain a simple blender cube, with a simple rotation animation (it’s ~5kb large).

Here is a screenshot : [Imgur: The magic of the Internet](https://i.imgur.com/LFrNWoo.jpeg)  
And another one : [Imgur: The magic of the Internet](https://i.imgur.com/bU33opf.jpeg)

As you can see, the number or the size or complexity of the objects displayed is fairly low and yet the CPU usage is very high. If I try to display 1000~ cubes, which seems reasonable, the CPU doesn’t quit the 100%. 2000 it crashes.

So I guess I am not using the good method ?

Here is the code repsonsible to display the cubes :

```auto
function addBox(viewer, longitude, latitude, modelUri) {
    const modelHeight = 50;
    const heightAboveTerrain = 50;
    const minimumVisibleDistance = 0;
    const maximumVisibleDistance = 10000;

    const terrainProvider = viewer.terrainProvider;
    const positions = [Cesium.Cartographic.fromDegrees(longitude, latitude)];

    return Cesium.sampleTerrainMostDetailed(terrainProvider, positions)
        .then((updatedPositions) => {
            const terrainHeight = updatedPositions[0].height;
            const positionHeight = terrainHeight + heightAboveTerrain;
            const position = Cesium.Cartesian3.fromDegrees(longitude, latitude, positionHeight);

            const hpr = new Cesium.HeadingPitchRoll(0, 0, 0);
            const orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);

            const scale = modelHeight / 50; // Assuming the original model is 50m tall

            const entity = viewer.entities.add({
                name: 'GLB Model',
                position: position,
                orientation: orientation,
                model: {
                    uri: modelUri,
                    scale: scale,
                    heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
                    distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
                        minimumVisibleDistance, 
                        maximumVisibleDistance
                    )
                }
            });

            return entity;
        });
}

```

I loop through 250 pairs of coordinates, and I display my 100 cubes like that :

```auto
    questBoxes.forEach(questBox => {

        addBox(viewer, questBox.lng, questBox.lat, './models/cube.glb');
    })
}

```

I am not even trying to display a BIG number of BIG models. Just 200 cubes, and the CPU is already through the roof.

Any idea ? How other people do ? It seems like a common usecase.

---

<div class="post-metadata">

**Author:** ![Dorian](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/dorian/32/14029_2.png) [@Dorian](https://community.cesium.com/u/Dorian)\
**Post date:** [August 19, 2024, 2:54am UTC](https://community.cesium.com/t/display-a-large-number-of-glb-models/34579/2 "2024-08-19T02:54:52Z")

</div>

I recommend avoiding the use of Glb models for this task. Instead, you should consider using Geometry along with instancing techniques. This approach is more efficient, especially when dealing with a large number of similar objects. Instancing allows you to draw many objects using a single draw call, which can significantly improve performance.

---

<div class="post-metadata">

**Author:** ![jjhembd](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/jjhembd/32/10144_2.png) [@jjhembd](https://community.cesium.com/u/jjhembd)\
**Post date:** [August 19, 2024, 11:34pm UTC](https://community.cesium.com/t/display-a-large-number-of-glb-models/34579/3 "2024-08-19T23:34:20Z")

</div>

Hi @adcomere,  
At first glance, I don’t see a major problem, as long as the `.forEach` loop only runs once at startup. Can you share your code as a [Sandcastle example](https://sandcastle.cesium.com/)?

Have you considered using a [BillboardCollection](https://cesium.com/learn/cesiumjs/ref-doc/BillboardCollection.html) instead of individual GLB models?

---

<div class="post-metadata">

**Author:** ![Marco13](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/marco13/32/2757_2.png) [@Marco13](https://community.cesium.com/u/Marco13)\
**Post date:** [August 20, 2024, 3:47pm UTC](https://community.cesium.com/t/display-a-large-number-of-glb-models/34579/4 "2024-08-20T15:47:27Z")

</div>

The following is a Sandcastle that loads and displays the “Plane” model 100 times:

> **[Cesium Sandcastle](https://sandcastle.cesium.com/index.html#c=hVVtb9s4DP4rQr7MuXqyu7YbLk2LZU1vO6C79tqu+7AMhWIzjnCyFEhymtyQ/z5asl3bzTAjLxL5kKLIh3SipLHEgtaMyxut1jwFTc4Ie2LckgswvMhpooFZ+Kq0SO89cmK2MgmGpzNJ/DOTifO05vDkHEh4qs0fnCyYDRK3v1DSogvQs0FIfpQeeseP+oJwJnflWd45NQlIoCnMi+xuqZ7+0iwHcwP6DjCGFM+2ugCEz+SikInlShKWph/UJvAOQiKUzLgtUsAls9UqVymIL5oPfVD+Pk74CXi2tOj4JD59Vi2ddDJXa6iy0kfkXPK8yB+44XMBU24skwkgqgNim/2gwxgfd40a+rJMVUZ6ipb3lTK8zIBB8LeqHhdMW5VptlryhC60yqeQaQAT7EnL8LtzVn412ELLuqiG5StRX/yzMnYKWFUBadAv3nMMQ2qXIIOgWKXIp/SmkZOzc5/03k2bxPctvsXfqc//adusPqmx6/o52FOzvfZo2coVrpg8+l2mwt7pw6p0DV1Wvbb4BCzlMrvhNlneKiGCOCTlZ9gJSWkO2C/dqO41k2ahdG4wC10v/xaYKC0RHtTxhOXZ/XBMwkTJsjbBo5K+JIrIxJgCyZsRrFcZQcYlEx5KuEFUTiwTou0Pg+R2+0xJt+dgKLZe8KOeExJbdURefbz6QD6X3l6FtaYOdtSsGlUrBaP2pgG4wEakOaV8Cs1HTUuHbY27+cj/dRSeHLewAA3YgqPnQnXk9PbyanL/98Pl4/3148fb6y//TDtu0qqFsZVXgm1x3KXVzVrFn/4CFLQ9ubvtnSEheYHbO0baqGG92fnFriZaPUQ0S/6D9LIupK/oaXVS1f2VsJQ5+13JKs8A6WYWypCYJBBgyeYM6bQZS/w5OKjGaqPclsptqdw2yppMwpH99eGbIxq/Oz5+e/gn9m5McR6+OSF/kE2nQ7ABS/DxMY1P4qN38dsOdlthX74BXOuGONsGlEZ3bpxNmWWRI42JfKEmXFerR1zSTMxnA5+3XXX5QTgYG7sVcF7n9z3PV0pbpKAI0LUFdI1NaaJ5gQm2NDGmTv04apuOU74mPD3b86YkiWDGoGZRCHHH/4fZ4HwcIf6FqVBuIFyvQSOxStjy8PzKCyml4wi3+y2tUmLOdM/zTw)**
>
> The Cesium Sandcastle provides an interactive environment for testing Cesium code.

There obviously are some race conditions in `sampleTerrainMostDetailed`, because they are not always ending up in such a nice grid. But in terms of performance, this should not be a problem:

![Cesium Many GLBs](https://global.discourse-cdn.com/cesium/original/3X/5/4/54da41734779728cb8341e9acc416bfcb45614fe.gif)

It’s running at 60FPS, with low CPU load.

When you are talking about the CPU load, then I assume that this refers to the time **while** these models are created. And yes, the CPU will be busy there - mainly because of `sampleTerrainMostDetailed`, which is a _very_ costly operation.

(Maybe you could improve the performance (or reduce the delay while loading) by **not** passing in each `position` individually, but instead, creating an array containing **all** the desired model positions, calling `sampleTerrainMostDetailed` only **once** (passing in this array), and then creating the models based on the resulting `updatedPositions`. But this is only a guess, and the details depend on factors that may require further investigations)
