3dstreet icon indicating copy to clipboard operation
3dstreet copied to clipboard

Use instancing to reduce draw calls for cloned objects

Open kfarr opened this issue 5 years ago β€’ 10 comments

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.

kfarr avatar Apr 26 '20 17:04 kfarr

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-geometry which 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

kfarr avatar Apr 27 '20 05:04 kfarr

Another good reference: https://discourse.threejs.org/t/create-buffergeometry-from-gltf-model/7946

kfarr avatar Apr 27 '20 05:04 kfarr

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;"

kfarr avatar May 03 '20 01:05 kfarr

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

kfarr avatar May 05 '20 04:05 kfarr

Check this out! https://github.com/EX3D/aframe-InstancedMesh

kfarr avatar Jun 08 '20 15:06 kfarr

Used modified instanced-mesh component to reduce draw calls by 34 for buildings image

kfarr avatar Jul 12 '20 07:07 kfarr

  • Works well for objects with one material. These could be converted next.
  • Will take more effort for objects with multiple materials.

kfarr avatar Jul 12 '20 07:07 kfarr

https://stackoverflow.com/questions/61590575/three-js-position-individual-instances-of-buffergeometry-from-loaded-gltf

kfarr avatar Oct 27 '20 04:10 kfarr

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

kfarr avatar May 12 '21 19:05 kfarr

Suggested repo for future reference: https://github.com/diarmidmackenzie/instanced-mesh

kfarr avatar Apr 19 '22 23:04 kfarr