EXT_mesh_gpu_instancing store custom attributes

We are looking at using EXT_mesh_gpu_instancing in order to improve performance of a gltf model containing > 30k 3D spheres. The current implementation stores a ID in the extras attribute so that a user can click on the sphere and the application can look it up via an ID. The problem is the 30k spheres starts to slow down cesium so we were hoping to use instancing for better performance.

We had some questions regarding instances before trying to implement it.

First, will this extension allow us to store attributes(ID) per sphere? We want something similar to node extras:

“nodes” : [ {
“extras” : {
“eventId” : “123-fssg151-afda”
},
“name” : “sphere[0]-node”,
“mesh” : 0,
“scale” : [ 0.56384295, 0.56384295, 0.56384295 ],
“translation” : [ -27.0, -10.962158, -103.5 ]
}

  1. Does the Model Entity API support this extension out of the box? Or do we have to use ModelExperimental?

There is a sample model GpuInstancesMetadata in the 3d-tiles-samples repository that uses this extension. This sample might be doing a bit more than what you are currently looking for: It does not only store identifiers for the objects, but also metadata for each instance, and this metadata is accessed via the identifiers.

But regarding the identifiers, there are two options:

  1. You can obtain the instance ID (which is just the index of the instance)
  2. You can assign your own feature IDs

For option 1., you can just add the EXT_gpu_mesh_instancing extension to an object, and then access the instance ID of that object, for example, when it is picked:

const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function (movement) {
  const picked = viewer.scene.pick(movement.endPosition);
  if (picked) {
    console.log(`Instance ID ${picked.instanceId}`);
  }
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

Option 2. is shown in the sample: The model defines a _FEATURE_ID_0 attribute inside the EXT_mesh_gpu_instancing extension. This feature ID attribute is connected to a property table that contains metadata for each feature ID (here, this is only a simple string). When the feature ID and the property table are defined like this, then the feature ID can be accessed like it is shown in the example sandcastle of this sample:

const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function (movement) {
  const picked = viewer.scene.pick(movement.endPosition);
  if (picked) {
    console.log(`Feature ID ${picked.featureId}`);
  }
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
1 Like