Use instancing to reduce draw calls for cloned objects
Right now objects such as trees, safe hit bollards, light posts, etc. are cloned with a very cumbersome approach to create new entities, each with its own entity that loads and parses a new glTF model for each of the cloned entities. This results in many draw calls and time to load and parse each object.
I think we can reduce draw calls and speed up the loading process by cloning in a more intelligent manner.
I tried A-Frame geometry merger to no avail: https://github.com/kfarr/streetmix3d/issues/8#issuecomment-619490868
Things to try:
- Try using the gltf-part component. Start with one type of object - lamp posts for instance. Put all of them in one glTF file. Their relative position many need to be "reset" and I have modified the gltf-part component here to try to do that.
- If that works, then create a new "master" blender file and export to glTF for all combined street props that are frequently repeated: trees, benches, light posts, etc.
Curious how instanced buffer geometry in Don's post here differs from buffer geometry in the gltf-part component: https://github.com/supermedium/superframe/blob/master/components/gltf-part/index.js#L72
Idea:
- For a given entity of a gltf model, create a component such as
instance-geometrywhich takes a gltf-part id and a rotation / position offset that will be assigned to the clones. See this: https://github.com/donmccurdy/three-shadenodeloader/blob/9086f85eda800424d6cd446b5412e98ed97591b4/index.html#L307
Another good reference: https://discourse.threejs.org/t/create-buffergeometry-from-gltf-model/7946
Ideal component syntax:
<a-assets>
<a-asset-item id="model-glb" src="model.glb"></a-asset-item>
<a-mixin id="model" gltf-model="#model-glb"></a-mixin>
</a-assets>
<a-entity id="cloned-models" clone_mixin="mixinId: model; step: 15; radius: 60; rotation: 0 0 0; positionXYString: 0 0; randomY: false;"
InstancedMesh is a higher level abstraction in threejs to help make this simpler than using InstancedBufferGeometry.
Three.js core - https://threejs.org/docs/#api/en/objects/InstancedMesh Third party class - https://github.com/pailhead/three-instanced-mesh#readme
Check this out! https://github.com/EX3D/aframe-InstancedMesh
Used modified instanced-mesh component to reduce draw calls by 34 for buildings

- Works well for objects with one material. These could be converted next.
- Will take more effort for objects with multiple materials.
https://stackoverflow.com/questions/61590575/three-js-position-individual-instances-of-buffergeometry-from-loaded-gltf
From thrax on threejs slack:
i have some instancing code that simplifies that instancedmesh stuff... https://gist.github.com/manthrax/3724dac17379782794bd0e602637d7c5 you make a new InstanceGroup().. add meshes to it, and it renders all its children instanced. and you can add/remove things from it and it transparently makes the instancedmeshes for each geom and stuff
Suggested repo for future reference: https://github.com/diarmidmackenzie/instanced-mesh