Tiles invisible while loading lower level

When first zooming in close on our high-res photogrammetry model (ID 1686494) and then zooming out quickly, tiles are invisible while loading and replacing with the lower levels. This doesn’t look right and I hope there’s just some configuration error that we could solve to make it behave better.

I have written my own script to convert to 3D Tiles. The model is built as an octree tile structure with 4 levels. The root level has geometricError set to float_max, next levels have about 0.24, 0.12, 0.06 and the highest has 0. The tile size of the highest level is 1.8 meters wide. As a proper octree, each tile is divided in up to 8 tiles in the higher level.

Is this behavior by design or can we do anything to avoid it? See screenshots below, directly after zooming out and after maybe one second.
before after

Hi @andek714 - the tileset structure you described is fine. I ran your tileset through the 3D Tiles Validator and it picked up several issues that would be worth fixing, though they aren’t the cause of the problem.

The problem is the tiles consume a lot of texture memory. When memory usage exceeds the tileset’s maximumMemoryUsage CesiumJS will start to unload tiles that aren’t needed for rendering. When you zoom out it needs to re-request those tiles and holes will appear until they are loaded.

I would suggest either increasing maximumMemoryUsage (which is 512 MB by default) or using lower res textures in non-leaf tiles.

Actually one point on the tileset structure - the root tile has way more than 8 children (121 to be exact) and since the root tile’s geometric error is so high it’ll refine to those tiles right away. Did you mean to skip a level?

Thanks Sean, excellent investigation and feedback indeed! I will run our photogrammetry pipeline again with different settings to produce one or two additional lower levels of this model.

And I will probably have to revisit my geometric error calculation, I can’t seem to wrap my head around it. We usually aim to switch our tiles to the next level when their projected bounding sphere has a radius of 700 pixels. I saw somewhere that the maximumScreenSpaceError in Cesium is 16px as a radius, so I tried calculating the geometric error like this but it seems to generate too high numbers - any suggestion?

geometric_error = tile_size * math.sqrt(2.0) / 2.0 * 16.0 / 700.0

I’m also confused about the top level geometric error and the root geometric error, I didn’t know what to set so I used float_max for both. Can you describe the difference between these two?

The 3D Tiles inspector looks neat, how can I use it with my own asset?

Only a short hint about that: The inspector can be enabled like it is shown in this sandcastle: Cesium Sandcastle , boiling down to calling
viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin);

Nice, thank you Marco! I managed to set my access token and load my asset in there. Great tool!

@andek714 since maximumScreenSpaceError can change at runtime so you probably want geometric error to be more physically based, i.e. derived from the decimation algorithm you’re using.

The difference between top level geometric error and the root geometric error is that the former determines when the root tile becomes visible and the latter determines when the root tile’s children become visible. float_max for both means the children will always be rendered.

Okay, I will think about a different way of setting the geometric error based on our own decimation.

I may have misinterpreted the root level somehow, I have no content there so level 0 is actually its children. I guess the result is the same with its geometric error set to max.

I can see now why I did it like this, a downloaded 3D Tiles asset generated by ION from an uploaded single OBJ file (or rather a ZIP with obj, mtl, jpg) actually doesn’t have any content in the root level, and the top and root geometric errors are the same. So my design is due to reverse-engineering rather than reading the specs. Is this behavior of ION correct or just misleading?

Oh I forgot that your root tile is an empty tile holding onto the transform. In that case it’s pretty standard for the tileset geometric error and root geometric error to be the same.

Ok thanks, good to know that I got that right anyway.