Weekly Video: Fun with Instance Buffers

Hey Gang,

Back with another weekly video.

This week @Deltakosh walks through some of the latest updates to instances: Instance Buffers!

15 Likes

Excellent! Nice feature, well presented. I wonder… hmm. Is there added horsepower for SPS… because of this feature? (beard scratch) Thoughts on that, anyone? Maybe that should be a separate topic-thread.

Wow, instances with their own private characteristics… nice. Even scaling? Even parent? hmm. I smell demented mad-scientist tests nearby. :smiley: I think I need to find a instance buffer playground to torture.

The SPS performance is related directly to the global number of vertices. It can compete with (or beat sometimes) instances when managing low poly objects (say, 2 or 300 vertices per object). It provides a way to set position/rotation/scaling/color of each object, just like instances. Its objects are pickable/intersectable and “parentable”, just like instances.
It provides a way to set a part of a global texture to each object (like a sprite sheet does). Instances can’t do this.

So if you need to render a bug number of high poly objects with the same material, whatever their positions/rotations/scalings/colors, instances used with instance buffers are the way to go.
If you need to render a very high number of only simple planar objects, no matter of the alpha sorting, particles (CPU or GPU ones), are the way to go.

If your need is between these two trends and if you need some extra features, then the SPS could help.
Those are 3 complementary tools with their own weakness and their own strength depending on what you want to achieve.

3 Likes

Btw, instance buffers, when using the world matrix buffer, can be really powerful : Babylon.js Playground

20K animated polyhedra (dodecahedron) at 60 fps !
[EDIT] All credits to @deltakosh who implemented the feature and spent a while helping me to find where the existing bottleneck could be before that feature

5 Likes

@Deltakosh : Interesting development - but can I change the texture too? You know me - not much of a coder :grin:

cheers, gryff :slight_smile:

1 Like

You can’t unfortunately. We can only instantiate mesh attributes (world matrix, color, uv, etc…)

1 Like

Does that mean you could do it with a texture packer and adjustment of uvs?

1 Like

Well not really as the uv in this case is per INSTANCE and no more per vertex

1 Like

The one bit you might add if it is true, to still freeze the matrix of instances which are not going to move / rotate to avoid needless checking. This might be just straps, but 10k of anything single-threaded might add up.

I was also wondering it the attributes included morph targets? For instance, say you made a really crude / low poly half person, and put 500 in very poor lighting (like an audience). You gave the person a key of clap. You might then animate them so they are not clapping exactly the same.

1 Like

Maybe I’m misunderstanding but I think @JohnK you mean something like this?

https://www.babylonjs-playground.com/#GPW8E9#10

I’ve been using instance buffers for texture atlases with great success so far.

3 Likes

Well got to the end of the day, so I just made my audience member with the clap shape key. Cheated here, by exporting as clapped, forgot to nuke UVS, & way still too many verts. All Fixable in 5 minutes.

I guess the property morphTargetManager.getTarget(0).influence is not going to work, at least directly. I could sub-class mesh and make a setter do that, but now that I look at InstancedMesh, it has no support for MorphTargets.

Unless, morphTargets on a mesh get transferred to the instance, & clapping all exactly the same looks ok, it does not appear this will work.

1 Like

@thrice : I really like the effect, though with my limited programming skills, I’ve no real idea about what you are doing :grin:

cheers, gryff :slight_smile:

@gryff In that example I have a numbers texture atlas, with the numbers 0-9, and I am using buffers to display one number at a time, using one source mesh, as well as set colors for each of them. There is a much simpler example here:

https://www.babylonjs-playground.com/#EK6GAC#11

But my playgrounds keep getting broken for some reason and it is broken here. But doing the same thing in the above playground, just displaying the numbers only

1 Like

What if you have an animated mesh? Is it possible to have each instance at a different currentFrame point of the animation?

Yes no problem

I couldn’t figure it out, some tips please? The instance doesn’t have a currentFrame attribute, its animations attribute is an empty array and apparently animations override doesn’t control this.

Ideally I’d like to do something like this:

const assetsManager = new BABYLON.AssetsManager(this.scene);
const task = assetsManager.addMeshTask('something', null, '/models/', 'scene.gltf');
task.onSuccess = (task) => {
  task.loadedMeshes.forEach((mesh) => {
    mesh.isVisible = false;
    for (let i = 0; i < 5; i++) {
      const instance = mesh.createInstance('something' + i);
      instance.position.x += i;
      instance.isVisible = true;
      // TODO what to set here?
    }
  });
};

setting a different currentFrame and if possible a different animation speed for each instance. Thanks!

Each instance is a regular mesh so you can create animation and call scene.beginAnimation(instance, …)

1 Like

Do you know if there is a known problem with the depthRenderer and instances? I get a TypeError: l.subMeshes is undefined from the code above when the scene.enableDepthRenderer(). I couldn’t find an issue on Github, let me know and I’ll open it.

Can you repro in the Playground?

Yes. Here’s it Babylon.js Playground Comment the enableDepthRenderer() call and it works, otherwise it crashes. I can create an issue on Github if you want.