How to improve scene rendering performance when there are a lot of dynamic entities in the scene?

672 views
Skip to first unread message

Jalien Super

unread,
Jan 17, 2019, 10:34:31 PM1/17/19
to cesium-dev
1. A concise explanation of the problem you're experiencing.

When I add a lot of entities to the scene, the engine renders a low frame rate,even though there are only a few entities in the field of view.It seems to be the frustum culling takes too much time.

0.PNG

1.PNG


2. A minimal code example. If you've found a bug, this helps us reproduce and repair it.

var viewer = new Cesium.Viewer('cesiumContainer', {
    infoBox : false,
    selectionIndicator : false,
    shadows : true,
    shouldAnimate : true
});
viewer.scene.debugShowFramesPerSecond = true;

//Create a model at the specified location 
function createModel(url, lon,lat,height) {
    var position = Cesium.Cartesian3.fromDegrees(lon, lat, height);
    var heading = Cesium.Math.toRadians(135);
    var pitch = 0; 
    var roll = 0;
    var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
    var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);

    var entity = viewer.entities.add({
        name : url,
        position : position,
        orientation : orientation,
        model : {
            uri : url,
            minimumPixelSize : 128,
            maximumScale : 20000
        }
    });
}

//Create a specified number of models with random locations
function addModel(count){
     for (var i=0;i<count;i++){
        var lon = Math.random()*120.0 - 60.0;//(-60,60)
        var lat = Math.random()*120.0 - 60.0;//(60,60)
        var url = "../../SampleData/models/CesiumAir/Cesium_Air.glb";
        var entity = createModel(url,lon,lat, 50000.0);
     }
}

addModel(5000);
var rectangle = new Cesium.Rectangle(Cesium.Math.toRadians(-60),
                        Cesium.Math.toRadians(-60),
                        Cesium.Math.toRadians(60),
                        Cesium.Math.toRadians(60));
viewer.scene.camera.flyTo({destination: rectangle});



3. Context. Why do you need to do this? We might know a better way to accomplish your goal.

I want to support more than 10,000 dynamic entities with high performance in my application.

4. The Cesium version you're using, your operating system and browser.

Cesium 1.5.2,Windows 10 x64,Google Chrome  71.0.3578.98.


Omar Shehata

unread,
Jan 23, 2019, 9:04:13 AM1/23/19
to cesium-dev
I think for this particle case, it might speed things up significantly to hook up the ModelInstanceCollection system to the Entity API. See the discussion on that here:


You can see an example of how the performance looks and using that directly even though the API isn't public yet:


This only works if they're the same model though.

Jalien

unread,
Jan 23, 2019, 10:19:36 PM1/23/19
to cesium-dev

Hi Omar,thank you so much for your reply.
I wrote an example comparing the performance of Entity and ModelInstance. After running the example, we can see that the frame rates of the two are almost the same, and ModleInstance has no obvious performance improvement.

var viewer = new Cesium.Viewer('cesiumContainer', {
    infoBox : false,
    selectionIndicator : false,
    shadows : false,
    shouldAnimate : false
});
viewer.scene.debugShowFramesPerSecond = true;
viewer._cesiumWidget._creditContainer.style.display="none";

var url = "../../../../Apps/SampleData/models/CesiumAir/Cesium_Air.glb";
var count = 5000;//entity number
var collection;
var useCollection = false;
var context = viewer.scene.context;
var instancedArraysExtension = context._instancedArrays;

//generate a random number(n,m)
function rd(n,m){
    var c = m-n+1;  
    return Math.floor(Math.random() * c + n);
}

//Create a model at the specified location 
function createModel(url, lon,lat,height) {
    var position = Cesium.Cartesian3.fromDegrees(lon, lat, height);
    var heading = Cesium.Math.toRadians(135);
    var pitch = 0; 
    var roll = 0;
    var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
    var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);

    var entity = viewer.entities.add({
        name : url,
        position : position,
        orientation : orientation,
        model : {
            uri : url,
            minimumPixelSize : 128,
            maximumScale : 20000
        }
    });
}

//Create a specified number of models with random locations
function addModel(){
     for (var i=0;i<count;i++){
        var lon =rd(90,130);//(90,130)
        var lat =rd(20,55);//(20,55)
        var entity = createModel(url,lon,lat, 50000.0);
     }
}


function reset() {
    if(collection){
        viewer.scene.primitives.remove(collection);
    }else{
        viewer.entities.removeAll();
    }
if(useCollection){
        addCollection();
    }else{
    addModel();
    }
}

//Collection
function addCollection() {
    var instances = [];
    for(var i=0;i<count;++i){
        var lon =rd(90,130);//(90,130)
        var lat =rd(20,55);//(20,55)
        var position = Cesium.Cartesian3.fromDegrees(lon, lat, 50000);
        var heading = Math.random();
        var pitch = Math.random();
        var roll = Math.random();
        var scale = (Math.random() + 1.0)/2.0;
        scale = 20000;
        var modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(position, new Cesium.HeadingPitchRoll(heading, pitch, roll));
        Cesium.Matrix4.multiplyByUniformScale(modelMatrix, scale, modelMatrix);

        instances.push({
            modelMatrix : modelMatrix
        });
    }

    collection = viewer.scene.primitives.add(new Cesium.ModelInstanceCollection({
        url : url,
        instances : instances
    }));
}

addModel();

var rectangle = new Cesium.Rectangle(Cesium.Math.toRadians(90),
                                     Cesium.Math.toRadians(20),
                                     Cesium.Math.toRadians(130),
                                     Cesium.Math.toRadians(55));
viewer.scene.camera.flyTo({destination: rectangle});

Sandcastle.addToolbarMenu([ {
    text : 'entity',
    onselect : function() {
        useCollection = false;
        reset();
    }
}, {
    text : 'instances',
    onselect : function() {
        context._instancedArrays = instancedArraysExtension;
        useCollection = true;
        reset();
    }
}]);

result:

entity.png

instance.png



在 2019年1月23日星期三 UTC+8下午10:04:13,Omar Shehata写道:

Omar Shehata

unread,
Jan 25, 2019, 10:51:25 AM1/25/19
to cesium-dev
I just tried running this on an old machine. The instance is about 3x faster. Have you tried this on other machines? What frame rates/time per frame are you getting for these tests?

Jalien

unread,
Jan 28, 2019, 11:03:29 AM1/28/19
to cesium-dev
I am sorry, you are right, I have only tested it on my laptop before, the graphics card is Intel HD Graphic 620. When I tested on a GTX 550 graphics card, the instance was indeed much faster than the Entity. In addition, when I simplified the model on my laptop, the instance can bring a big performance boost . Perhaps the frame rate is related to memory and graphics speed. Thanks again.

在 2019年1月25日星期五 UTC+8下午11:51:25,Omar Shehata写道:
Reply all
Reply to author
Forward
0 new messages