Cesium 3D Tiles - Huge 3D tiles model - issues: tearing, performance

1,151 views
Skip to first unread message

Alex Dunmow

unread,
Mar 13, 2017, 7:00:04 AM3/13/17
to cesium-dev
Hi all,

We're currently loading a HUGE 3D tiles model into Cesium. 

We're not sure if we're using the correct functionality / features.

It is rather slow, but that's to be expected due to the size & complexity of the model. But we're not sure if there's anything else we can do to improve performance.

We've also noticed weird tearing on the floor of the 3d tiles. If the camera is over them the floor will tear like this: 

















Is there any way we can stop this from happening?

Thanks all for any help given.

Here is the code:

viewer = new Cesium.Viewer('cesium', {
  scene3DOnly: true,
  homeButton: false,
  infoBox: false,
  sceneModePicker: false,
  geocoder: false,
  baseLayerPicker: false,
  selectionIndicator: false,
  timeline: false,
  animation: false,
  credits: false,
  contextOptions: {
webgl: {
preserveDrawingBuffer: true
}
}
});
// No depth testing against the terrain to avoid z-fighting
viewer.scene.globe.depthTestAgainstTerrain = false
 
var heightOffset = 4.0;
var heightOffsetSouth = 5.1;


var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
url : '/3dmodel/SouthTiles/tileset.json',
maximumNumberOfLoadedTiles: 0,
maximumScreenSpaceError: 100
})
);

tileset.readyPromise.then(function() {
console.log('Loaded south tileset',tileset);
var boundingSphere = tileset.boundingSphere

var bounding = tileset._root._boundingVolume;
var center = bounding.boundingSphere.center;

var cart = Cesium.Ellipsoid.WGS84.cartesianToCartographic(center);
var dest = Cesium.Cartesian3.fromDegrees(
cart.longitude * (180 / Math.PI),
cart.latitude * (180 / Math.PI),
bounding._boundingSphere.radius * 20.2);

var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center)
var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0)
var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, heightOffsetSouth)
var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3())
tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation)

// viewer.camera.setView({ destination: dest });
}).otherwise(function(error) {
console.log(error);
});

var tileset2 = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
url : '/3dmodel/NorthTiles/tileset.json',
maximumNumberOfLoadedTiles: 0,
maximumScreenSpaceError: 100
}))

tileset2.readyPromise.then(function() {
console.log('Loaded north tileset');
var boundingSphere = tileset2.boundingSphere

var bounding = tileset2._root._boundingVolume;
var center = bounding.boundingSphere.center;

var cart = Cesium.Ellipsoid.WGS84.cartesianToCartographic(center);
var dest = Cesium.Cartesian3.fromDegrees(
cart.longitude * (180 / Math.PI),
cart.latitude * (180 / Math.PI),
bounding._boundingSphere.radius * 20.2);


var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center)
var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0)
var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, heightOffset)
var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3())
tileset2.modelMatrix = Cesium.Matrix4.fromTranslation(translation)

// viewer.camera.setView({ destination: dest });
}).otherwise(function(error) {
console.log(error);
});


 

nii236

unread,
Mar 13, 2017, 10:00:12 AM3/13/17
to cesium-dev
Any help would be much appreciated! Even just where to start looking through the APIs. I had a search for cameras and collisions but no luck unfortunately.

On Monday, March 13, 2017 at 7:00:04 PM UTC+8, Alex Dunmow wrote:
> Hi all,
>
>
> We're currently loading a HUGE 3D tiles model into Cesium. 
>
> We're not sure if we're using the correct functionality / features.
>
>
> It is rather slow, but that's to be expected due to the size & complexity of the model. But we're not sure if there's anything else we can do to improve performance.
>
>
> We've also noticed weird tearing on the floor of the 3d tiles. If the camera is over them the floor will tear like this: 
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

Sean Lilley

unread,
Mar 13, 2017, 7:12:29 PM3/13/17
to cesium-dev, jtngu...@gmail.com
Could you enable the 3D Tiles inspector (like in the 3D Tiles sandcastle) and post a screenshot of that? I might have some tips when I see those numbers.

For the clipping, it's hard to tell from the screenshot but is that due to intersecting with terrain, or is it just the geometry at fault?

Alex Dunmow

unread,
Mar 13, 2017, 7:23:29 PM3/13/17
to cesium-dev, jtngu...@gmail.com
Hi Sean,

The clipping is purely from geometry, as our model is currently positioned about 4m hovering over the ground.

Here's a screenshot with the tile inspector:


Thank for your the quick response

Sean Lilley

unread,
Mar 13, 2017, 8:27:42 PM3/13/17
to cesium-dev, jtngu...@gmail.com
Ok so looking at the Selected and Commands numbers, each tile is averaging about 2.88 draw commands. Since this tileset is textured I don't see why there couldn't be better batching within each tile to bring that number down to 1. Reducing the number of draw calls (aka commands) will make a huge difference with performance.

Another observation is the tile bounding boxes seems to be overlapping a lot especially noticeable in the center of that image. Maybe the tiling could be improved? With this view 433 tiles are selected, which seems pretty high. About how large is each tile in MB? If possible try join smaller tiles together.

Finally the maximum screen space error you have set is unusually high. To get better performance you could set this even higher, but really the tiles should have more reasonable values.

Alex Dunmow

unread,
Mar 13, 2017, 9:43:10 PM3/13/17
to cesium-dev, jtngu...@gmail.com
Hey Sean, thanks for the response, We'll do some work on the model.

Any hints on the clipping?

Sean Lilley

unread,
Mar 14, 2017, 9:39:33 AM3/14/17
to cesium-dev, jtngu...@gmail.com
You should verify that the normals are pointing in the right direction. To test that remove 2929 (CULL_FACE) from the states section in the glTF and see if the surface is now solid.

Patrick Cozzi

unread,
Mar 19, 2017, 11:22:33 AM3/19/17
to cesium-dev, jtngu...@gmail.com
Hi Alex,

Cool dataset.  Can we showcase your work at the top of the 3D Tiles spec:


This helps show adoption for the OGC community standard process.

Please send me a quick note: pco...@agi.com

Patrick

zhang...@gmail.com

unread,
Apr 8, 2018, 10:29:57 AM4/8/18
to cesium-dev
Hi Sean,

I found the number of draw commands really impact the performance. But how to reduce it?

I turned on the debugShowRenderingStatistics option in this sandcastle example: https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/?src=3D%20Tiles%20BIM.html&label=Showcases and found that the tileset has 27216 features but only 14 commands, while my own tileset always has more commands than feature count. For example, if I draw 4 objects like cubes and balls with Windows 3D Builder and convert the obj file to a b3dm, after I load it, I get a 5 commands statistic.

I tried a convert tool called obj23dtiles, and the official obj2gltf + 3d-tiles-tools. I even got 0 features / 5 commands with the latter tools.

Are there anything wrong with my procedures?

Thank you very much.

zz

> Ok so looking at the Selected and Commands numbers, each tile is averaging about 2.88 draw commands. Since this tileset is textured I don't see why there couldn't be better batching within each tile to bring that number down to 1. Reducing the number of draw calls (aka commands) will make a huge difference with performance.
>
>
> Another observation is the tile bounding boxes seems to be overlapping a lot especially noticeable in the center of that image. Maybe the tiling could be improved? With this view 433 tiles are selected, which seems pretty high. About how large is each tile in MB? If possible try join smaller tiles together.
>
>
> Finally the maximum screen space error you have set is unusually high. To get better performance you could set this even higher, but really the tiles should have more reasonable values.
>
> On Monday, March 13, 2017 at 7:23:29 PM UTC-4, Alex Dunmow wrote:
> Hi Sean,
>
>
> The clipping is purely from geometry, as our model is currently positioned about 4m hovering over the ground.
>
>
>
> Here's a screenshot with the tile inspector:
>
>
>
>
>

Sean Lilley

unread,
Apr 9, 2018, 10:40:55 PM4/9/18
to cesium-dev
It depends on your model, but the best way to reduce draw calls is to combine as many nodes/meshes/primitives together as possible. Each primitive in the glTF will become a draw call so you'll want to minimize the total number of primitives.

This isn't always possible if each primitive has a different material on it. Some people get around this with texture atlases or vertex colors, though most of the simple converters out there won't do optimizations like that.

For a super simple test, try removing all the following lines from the obj:
  • usemtl
  • o
  • g
And then run it through obj2gltf. That should give you a glTF with one primitive.

Zhe Zhang

unread,
Apr 10, 2018, 3:45:32 AM4/10/18
to cesiu...@googlegroups.com
I have tried it. It seems that each object / primitive in an obj file will be represented by a feature in the converted tileset. If I removed the following lines, I lost the object / feature information. How to keep the features?

Sean Lilley

unread,
Apr 10, 2018, 7:24:19 PM4/10/18
to cesium-dev
Oh true the features will get lost with that method. I know the obj2gltf + 3d-tiles-tools workflow doesn't preserve features at all, so you might have to look closer into what obj23dtiles is doing. One thing to try though it remove the usemtl lines but keep the o and g lines, and see what happens.
Reply all
Reply to author
Forward
0 new messages