Performance Improvements to Instancing

Hey folks, some general thoughts about instancing as you seem to be putting some energy behind rendering at the moment and I’d love to see this pushed further…

I’ve uploaded a sample scene of instanced spheres (spheres | Speckle) generated from this script here:

example-of-instancing.ghx (102.0 KB)

There’s two things I’d like to highlight here -

  • the instances are slower to load in the viewer than you might expect for an array of transforms and a single mesh
  • each transform gets diffed as an individual object, so when you’re procedurally populating, say, a landscape with trees at random, each instance transform is a new object, and all the instances need to be diffed with the server every commit.

Potentially, some of this could be fixed by, as well as having the current BlockInstance setup, having another pattern that takes a definition and an array of transforms, and holds all the instances as a single array of doubles, like a mesh would.

To slim things down even further for the likes of trees and people, you could even have the blockDefinition, and an array of positions, and then use the origin of the blockdefintion as the pivot and have the mesh orientate to face the camera (similar to a billboard in godot or unity, or the default man in sketchup)

Thanks, @chris.welch. Putting viewer performance (@alex at the ready) and the orbit suggestion aside, your spheres script is a simple illustration of your pint: could an array-based transform approach improve performance?

For me, I wonder: “What about instance properties?” If these instances include data beyond transforms, isolating transforms might not deliver the expected gains, as the whole instance will still end up being re-diffed. For sure if nothing else changes some parts will be fine but we’ve seen that infinite/excessive detaching has been a performance hit in the past too.

For the benefit of others reading (and the Google bots), Speckle has long relied on detaching and chunking as optimisation strategies. Proxies, being introduced in next-gen connectors, expand on this by handling materials, profiles, colours, and other properties more efficiently. They bring benefits beyond detaching by retaining relationships between objects, adding another layer of performance improvements.

The procedural workflows you highlight—like populating landscapes—are a great use case to consider, as these often amplify inefficiencies in transform diffing. I’d hope any instancing optimisation in next-gen Proxies will benefit such scenarios as well.

Forgive my ignorance here (and the inevitable gaps of a small-hours of the night reply), but I’m speculating, and it’s entirely possible the next-gen team already has a solution in mind for instancing and definitions.(Perhaps they’ll chime in???) Either way, this is a great thought experiment, and your input helps keep the conversation forward-thinking. Thanks as always!

2 Likes

Hi @chris.welch

Thank you for your input. We’re always happy to see people engaging in technical discussions and bringing up topics for improvement! :starstruck_spockle:

I agree with @jonathon regarding other properties stored on the instance objects. It’s true that for your particular case, only the transform data is relevant, however we need to accommodate a larger area of ​​applicability so we give the instance object full speckle object privileges. That’s the main reasons why you might consider that the load time is higher than expected.

However, I find that the 5 seconds it takes to load everything is acceptable considering there are over 20000 objects in the stream. Could if be faster if we just use an array of concatenated transforms? Sure, but what about the other properties that the instance objects might want to store. Maybe we could come up with a way to satisfy both. So let’s say cases such as yours where the instance objects hold nothing but the transforms are somehow simplified and minified for optimal storage and transfer and there is also support for regular instance objects when there is a need for it. The problem with this is that you add complexity. And that is something we really want to avoid :smiley_spockle:

Cheers