The two questions are fairly unrelated, and for both, there are several options of how to address them. The “best” solution usually involves several engineering questions and a clear idea about the intended application patterns. But I’ll try to give a short summary:
What we want is to put this model, say, in three different geographic positions. What is the right way to do this and how some simple tileset.json can look like? Can I use my glb model or should this instancing be hardcoded inside gltf first, and then packed in glb model?
And some relative question is about EXT_mesh_gpu_instancing. Khronos readme about this extension is rather short and not so informative. So, am I right to say that this extension is just some optimization, that can be applied to glb/gltf and improve rendering/visualization?
Indeed, the main options are:
- refer to this GLB file, multiple times, from a tileset JSON file
- create the instances in a single GLB, with
EXT_mesh_gpu_instancing
The advantage of option 1. might be that it is a bit easier and more flexible. For example, you could change the position of one of the trees without having to create the GLB file and its EXT_mesh_gpu_instancing
data. You could also more easily show/hide a single tree, or select it by clicking on it. (This is also possible with EXT_mesh_gpu_instancing
, but with much more effort)
The advantage of option 2. is mainly/only performance. With EXT_mesh_gpu_instancing
, you could easily and efficiently render 100000 trees. In contrast to that, having a tileset JSON that contains 100000 tiles that should all be rendered will be slow.
So when you only want to put it in three (or “few”) positions, then the easiest solution might be to just reference that model from a tileset.json
, from three different tiles, where each tile has a different transform
matrix.
For the given tile, such a tileset JSON (for two trees) could look like this:
{
"geometricError": 1000.0,
"root": {
"geometricError": 1000.0,
"refine": "ADD",
"boundingVolume": {
"box": [
1254723.2027332075, -4733011.404296879, 4073472.2598072663,
11.931891988846473, 0, 0, 0, 18.70224343938753, 0, 0, 0,
18.34575758059509
]
},
"children": [
{
"geometricError": 900.0,
"transform": [
0.9666108723721498, 0.2562487490934376, 0, 0, -0.1645317843574858,
0.620639953066638, 0.7666389897426187, 0, 0.1964502821278028,
-0.7410415826696163, 0.64207839039047, 0, 1254719.4320267234,
-4733000.450009609, 4073473.670362134, 1
],
"boundingVolume": {
"box": [
0.8377834740791688, 0.38224225730407735, 7.952663400546863,
7.760191485177515, 0, 0, 0, -7.9996707314338495, 0, 0, 0,
8.4149664158071
]
},
"content": {
"uri": "849af735-3acc-4978-a70c-97580db543fa.glb"
}
},
{
"geometricError": 900.0,
"transform": [
0.9666108723721498, 0.2562487490934376, 0, 0, -0.164531235764166,
0.6206378836857364, 0.7666407827607444, 0, 0.1964507415864546,
-0.7410433158204309, 0.6420762495280394, 0, 1254722.3549911848,
-4733011.475894566, 4073460.0507147997, 1
],
"boundingVolume": {
"box": [
0.8377834740791688, 0.38224225730407735, 7.952663400546863,
7.760191485177515, 0, 0, 0, -7.9996707314338495, 0, 0, 0,
8.4149664158071
]
},
"content": {
"uri": "849af735-3acc-4978-a70c-97580db543fa.glb"
}
}
]
},
"asset": {
"version": "1.1"
}
}
And when this is rendered, it will look like this
Should I apply this extension only to those models, that can have multiple instances (like trees) or should I use it even for sigle models (like some unique building)?
As I said above: This extension is intended for the case where you have many instances of the same model. An example where a user has used this extension to create many trees can be found at From I3dm to EXT_mesh_gpu_instancing? - #10 by bertt (the link at the bottom now should point to https://bertt.github.io/cesium_3dtiles_samples/samples/1.1/trees/ )
What is the best practice to combine multiple instances with LODs?
This mainly depends on which of the approaches you are going to use. A basic example of a tileset with LODs can be found at https://github.com/CesiumGS/3d-tiles-samples/tree/main/1.0/TilesetWithDiscreteLOD, and you could use that when you refer to the instances directly from the tileset JSON (i.e. with option 1.).
For option 2.,when using EXT_mesh_gpu_instancing
: In the most simple case, you could just create three separate GLB files, which contain the same EXT_mesh_gpu_instancing
information, and use this to instantiate different models. But one might have to put more thought into that, and whether it really makes sense, depending on the exact model and use-case.