Minimizing draw calls: Many objects with different textures

Hello all.

I’m attempting to create a network graph in Three.js, as many before me have done. However, I have some unique requirements.

Generally speaking, so far the graph just consists of nodes and edges with the following characteristics:

  • Graph:
    • Contains nodes and edges
    • All nodes and edges may be interacted with via the user’s mouse
    • May have it’s layout change (i.e., the positions of nodes) and these changes will be animated
  • Nodes:
    • Are the same shape when not expanded. As such, I could use InstancedMesh, except I also have the following requirements:
    • Have a unique bitmap image associated with them. Each one is different picture of a person or a logo for an organization, etc.
      • Maybe I could hide these using some LOD scheme, but its preferable to avoid it
    • Have text labels that may be expanded
      • Again, maybe I could collapse these at specific zoom levels when the graph is being laid out/animated
  • Edges:
    • For now, they will just be solid straight lines between any two nodes.

Now, onto problems and solutions I’ve discovered:

  • Edges:

    • PRO: Thankfully, I can use a single THREE.LineSegments object for all of the edges, and simply update the points whenever a node moves. At worst, this removes 50% of the unnecessary draw calls. At best, up to 80% of the draw calls can be batched into a single call. Awesome!
    • CON: This unfortunately will make user interaction via the mouse with a specific edge more difficult. I’m still not sure how exactly to overcome this.
  • Nodes:

    • PRO: Nodes tend to all be circles. Sometimes the scale will change, but that’s about it. This means that THREE.IntancedMesh is a perfect solution. I can also easily detect when the user mouses over a given node since it’s just a simple circle with a given (x, y) and a radius.
    • CON: Each node needs to have a unique texture, and may even have a text label associated with it.

I’m not opposed to diving into writing shaders to solve this problem. I just need to know where to start. After looking around, it appears as though custom shaders may only render a finite set of uniforms.

Is there a good way to solve this problem? I’d like to batch the drawing of these Nodes and Edges, but I need to maintain interactivity and uniqueness as well.

Any reading material or key terms to point me in the right direction would be helpful.