Problem with b3dm generated by DJI TERRA

When you upload b3dm generated by DJI TERRA, the details are displayed differently in the viewer.
When I upload OBJ, it will load normally.
All of them were made differently in the output format under the same conditions.
Can you analyze what’s wrong with the b3dm made in terra?

Asset number of b3dm: 2677386
asset number of obj: 2678825

Is there a problem with .json in b3dm? or is there a problem with b3dm files?
Looks like there’s someone else’s case with similar issues?

The b3dm made by Pix4Dmatic looks normal.
Asset number: 2676773

You can see three below.
https://ion.cesium.com/stories/viewer/?id=58c4458c-4365-4aff-a60f-861b83c0ebb7

Is there a problem with Terra’s code writing?

Hi,

Different tilers will create different outputs from the same source data. They make different decisions when it comes to how to process and optimize the data. That is why the tilesets appear different.

I looked into these assets and both 2676773 and 2677386 were added using the 3D tileset option. This means that another program (DJI Terra or Pix4Dmatic) had already converted the source data into 3D tiles and Cesium ion is just displaying the 3d tilesets they provided.

2676773 - tiled by Pix4Dmatic
2677386 - tiled by DJI Terra
2678825 - tiled using the reality capture tiler by Cesium

Since 2676773 and 2677386 were tiled by other programs you should contact support or those programs if you have issues with them. If you do find issues with the tileset that was created by Cesium please let us know and we can investigate further.

There are some guesses involved in the following. Analyzing the details of multiple data sets can be time consuming. But I did have a short look, and will try to summarize some aspects that may explain what you are seeing.

Just to confirm (and show) the behavior that you are (probably) referring to: For the data set that is generated with DJI TERRA, the initial representation looks washed-out and coarse, and does not show many details. Only when zooming in, the details appear. In contrast to that, the data set that was generated with another tool, it immediately shows a high detail (and only little additional detail when zooming in) :

Cesium DJI LODs


Looking more closely at the tileset JSON files, one can see the following:

(I’m omitting stuff like the bounding volumes and transforms here)

For the data set that was generated with DJI TERRA, the relevant part of the root tileset.json looks like this:

{
    "geometricError": 451.971435546875,
    "root": {
        "children": [
            {
                "content": {
                    "uri": "Block/tileset.json"
                },
                "geometricError": 348.6705017089844,
                "refine": "REPLACE"
            }
        ],
        "geometricError": 451.971435546875,
        "refine": "REPLACE"
    }
}

It just refers to a Block.tileset.json which looks like this:

{
    "geometricError": 348.6705017089844,
    "root": {
        "content": {
            "uri": "Block_L14_1.b3dm"
        },
        "geometricError": 5.55034065246582
    }
}

What’s happening now is the following: CesiumJS will …

  • load the root tileset.json, and see that it has a high error geometric error of 451
  • try to reduce that error, by loading the next level of detail - namely, the Block/tileset.json. This still has an error of 348.
  • try to reduce that error, by loading the next level of detail. Namely, the tile with the content Block_L14_1.b3dm. This has a geometric error of only 5.55
  • Here, CesiumJS will say “OK, that’s a pretty low error”, and stop refining the data

The Block_L14_1.b3dm file has a size of 12 KB (Kilobytes!!!), and … when it is rendered, it looks like this:

:face_with_diagonal_mouth:


Comparing that to the tileset that was generated with Pix4D:

{
    "geometricError": 293.72975158691406,
    "root": {
        "content": {
            "uri": "Osong_80m-cesium_mesh_0.b3dm"
        },
        "geometricError": 6.509479341772257
    }
}

Similar to the process above, CesiumJS will…

  • load the root tileset.json, and see that it has a high error geometric error of 293
  • try to reduce that error, by loading the next level of detail. Namely, the tile with the content Osong_80m-cesium_mesh_0.b3dm. This has a geometric error of only 6.5
  • Here, CesiumJS will say “OK, that’s a pretty low error”, and stop refining the data

The Osong_80m-cesium_mesh_0.b3dm has a size of 6.5 MB (Megabytes!), and looks like this:


The tl;dr of all this technical gibberish could be:

CesiumJS has to assume that the data that is shown in these screenshots has roughly the same visual quality - because the tiles have roughly the same geometricError value. So both data representations are shown at the same time, even though they obviously do not have the same visual quality.

But to emphasize that:

The output from DJI TERRA is not ‘wrong’!

(Except for the fact that the glTF has validation errors. This should be fixed by DJI TERRA, and if you can, you should file a bug report for that! But it is unrelated to the issue that you see here…)

The problem is only that different creation tools have different … attitudes … and make different decisions about how to structure the data, and what levels of quality they want to deliver. There are good, valid reasons to structure the data like DJI TERRA did: The client only has to download 12 KB (!) of data, and will immediately see an approximation of the model. For the Pix4D data, the client will have to download 6.5MB until the first data will become visible.

There is no “right” or “wrong” here. These are just trade-offs.


Maybe a solution:

You can tweak the behavior of CesiumJS, to accomodate for different geometricError values. Namely, by setting different maximumScreenSpaceError values for the tilesets. Skipping some details (pun somewhat intended :slight_smile: ), you can set a maximumScreenSpaceError for the DJI TERRA tileset that is lower than the default value. The default value is 16. So when you create that tileset with

const tileset =  await Cesium.Cesium3DTileset.fromUrl("./dji/tileset.json", {
    maximumScreenSpaceError: 2.0
});

then it should load more details faster. (You might even consider reducing the value, to 1.0 or even lower, until it matches the behavior that you’d expect).

I am touched by your kind explanation.^^

I am not an expert but I understand what you are saying very well.
Cesium JS is looking at the sample for now by adding the code “maximumScreenSpaceError = 1” for JavaScript code.
It’s being rendered to the level I want.
It wouldn’t be a problem if you used other tools to access assets.
At the moment there was a question at the stage of progress. Clear resolution.

Thank you again.