Bad lag (~200ms and increasing) in PushMaterial

Heya - has anyone come across a problem that as your scene grows (cryptovoxels is loaded as you explore the world), PushMaterial starts taking an inordinate amount of time?

I’ve been digging into PushMaterial#constructor and Material#constructor and can’t see anything in there that would take so much time - am I missing something?

We’re using our own material class like this:

const material = new BoundMaterial('feature/image', this.scene)
material.diffuseTexture = texture
material.alpha = 0.999
material.specularColor.set(0, 0, 0)
material.emissiveColor.set(1, 1, 1)

And BoundMaterial is:

export default class BoundMaterial extends BABYLON.StandardMaterial {

  boundMesh: BABYLON.Mesh

  bindMesh (mesh) {
    this.boundMesh = mesh

  markDirty (...args) {
    if (this.boundMesh) {

  markAsDirty (...args) {
    if (this.boundMesh) {

We would need to know which part of PushMaterial is taking time. A repro would probably help in that matter too.

I wonder if it is because it flags everything as dirty during each material creation introducing latency as we fixed for gltf loading.

The repro would definitely help ensuring this and addressing it.

Ok, I created this playground and it doesn’t seem to replicate the lag we’re getting…

Doing a bit more investigation.

1 Like

Man this lag is crazy. I’ll update once I work out how to fix it.

yup definitely need to understand what is taking so long there, keep us posted !!!

Ok - I have NFI where this while loop is coming from, I can’t see it in the babylon.max.js, but there it is…

Ok - worked out how to fix it. We’re not using getMaterialById anywhere else, so we can just nerf it.

ganymede:cryptovoxels$ git show 6419aae5dd4e141197a4798d3a44c972c2b42900

    Nerf scene.getMaterialById

diff --git a/src/lib/bound-material.ts b/src/lib/bound-material.ts
index 14788966..b43983a2 100644
--- a/src/lib/bound-material.ts
+++ b/src/lib/bound-material.ts
@@ -1,6 +1,13 @@
 export default class BoundMaterial extends BABYLON.StandardMaterial {
+  constructor (name, scene) {
+    // FITE ME
+    scene.getMaterialByID = () => {}
+    super(name, scene)
+  }

Yes - cryptovoxels is dirty hacks on top of dirty hacks. It’s basically a pile of hacks all the way down.

Would all your materials have the same name by any chances forcing to over all the mat on every creation ?

In this case simply create unique name for the materials ?

The thing is that getMaterialByID is looping over all existing materials in the scene until a match is found, if any. So there is always at least a full loop done over the existing materials when creating a new material. Maybe we should add a parameter to the Material constructor to allow disabling this loop? It was added some weeks ago to be sure to have unique material ids, but if people don’t want that / know they have unique ids in the first place they could save some performances.

Yes we have tonnes of materials with the same name. :slight_smile:

I guess it’s o(n^2) complexity to find a unique material name where n is number of same named materials?

1 Like

Yup agree @Evgeni_Popov we should allow a way to by pass this for perfs could you take care of it ?

@bnolan you wont need your dirty hack in a bit :slight_smile: just seen your twit

1 Like

PR is created:

Will be in on Monday at max :slight_smile: Thanks a ton for the PR

We will actually use a more global approach to prevent the incurred lag Rework #9290 due to perf hit by sebavan · Pull Request #9492 · BabylonJS/Babylon.js · GitHub

You ll be able to have it in the next nightly in about one hour @bnolan

1 Like