About material.freeze method

When I call the material.freeze method and I change the color of the material, why does the color change take effect in the scene? Looks like the actual situation doesn’t match the description on the website.


this is my test : https://www.babylonjs-playground.com/#EPI4MZ#15

Welcome aboard!

I don’t see any color change when I click?

Thank you very much for your reply. Are you using version 6.10?
Here’s what happened when I clicked…

Thank you very much for your reply. Are you using version 6.10?
Here’s what happened when I clickek

Yes, I’m using the Playground which is currently in 6.10.0. Which OS and browser are you using?

macOS Ventura 13.4 & chrome 114.0.5735.198

I tried it on the windows system,I don’t see any color change when I click :open_mouth:

line 34 is always called during rendering (fps/s)
so you need to change this to call it only once.

See the following PG

ps.
@Evgeni_Popov
I found this about

mat.freeze();


mat.unfreeze();
–change Material Options–
mat.freeze();

If you change the material’s options as soon as you unfreeze it, and then freeze it afterwards, it won’t unfreeze.
with a small delay, but…
This seems to be more of a bug

You should normally be able to simply call material.markDirty() / material.markDirty(true) to update a frozen material, without having to call unfreeze.

However, we have an issue in the tracker to improve the management of frozen materials:


I found that my local project references the @babylonjs/core dependency package, and calling markDirty does not work after the material is frozen. And it’s normal on the playground.
This is my local pull 6.10.0 version code and playground code screenshots, they are not the same!
In addition, my local @babylonjs/core also has problems with morph under webGPUEngine. Modifying the influence from 0 to 1 will cause the model to scale, but the playground is normal.
Why is the code referenced by 6.10.0 @babylonjs/core and playground different?

It seems your local version is messed up, you should probably reinstall the repo.

There’s another project that references an older version of babylon, version 5.32.0 :smiling_face_with_tear:

Good news, the WebGPUEngine morph issue is now fixed after the update.
The markDirty of the material is still invalid, seemingly because subMesh.effect is null. Under what circumstances does effect become null?

If you call resetDrawCache(), for example.

I did call resetDrawCache, because the affected materials sometimes don’t recompile when the lights in the scene are destroyed. After fixing the version, this issue does not seem to exist either.

Thank you so mush. This sentence should be deleted,“scene.onAfterRenderObservable.add(() => mat.freeze());”.But it still toke effect when I clicked.Probably because chrome & macOS doesn’t support ubo.

// packages/dev/core/src/Materials/standardMaterial.ts

   if (mustRebind) {
       this.bindViewProjection(effect);
       // ubo.useUbo is always false(chrome & macOS)
       if (!ubo.useUbo || !this.isFrozen || !ubo.isSync || effect._forceRebindOnNextCall) 
       {
           // ...
           ubo.updateColor4("vDiffuseColor", this.diffuseColor, this.alpha);
           // ...
        }
    }

I’ll read it. Thank you very much!!!

Yes, we force the deactivation of uniform buffer support in macOS because of some bugs (I don’t remember exactly where…).

You can reenable them by doing engine.disableUniformBuffers = false;

I’ll have a try and hope I don’t run into those bugs, hhh.
I have a question I want to confirm with you again.In rendering optimization, material.freeze can play a great effect. It doesn’t just reduce the computation on the CPU, right?

Yes, it reduces the load on the CPU side only, but CPU is generally the bottleneck on the web, GPU rarely is.