Effect recalculation on setParent

Hello! Please check this PG (Babylon.js Playground) where:

  1. There are two meshes on the scene, a box and a sphere
  2. The box has some rotation
  3. At some point I want to make the sphere a child of the box, so I do sphere.setParent(box)
  4. After that the sphere’s scaling vector becomes non-uniform (because of the floating point errors that appear in the matrices calculations because of the box rotation)
  5. This can’t really be shown in the playground, but now the sphere’s material becomes marked with _areMiscDirty = true flag which leads to an unnecessary effect recalculation

If that happens in the beginning of some animation (like in our project) AND effect recalculation is relatively heavy (i.e. for PBR for multiple meshes at once), then this leads to quite a few consequent frame drops.

Now I don’t know what could be fixed there really, but maybe the isNonUniform check could use some Scalar.WithinEpsilon checks instead of a strict !==?

Thanks!

https://www.babylonjs-playground.com/#FQB791#1

mesh.parent = mesh

weird that setParent does not work, let me look at that function really quick.

@Pryme8

why do you think setParent doesn’t work?
It shows me that sphere’s parent is box https://www.babylonjs-playground.com/#FQB791#2

(And also this is not really what my issue is about :upside_down_face:)

Man its early… let me go get some coffee. I’m not using my brain one second. Ill figure this out. I keep saying the wrong things, then think about it and feel dumb… so let me stop that.

@Pryme8 no worries :slight_smile:

For what I’ve found so far - there’s an ignoreNonUniformScaling property on the TransformNode that can prevent extra effect recalculation, but is it the correct way to go?
I feel that if i set it to true now, it might break something else for this mesh in the future.

Looking at it now it could be at any step along the way of the matrix calculations. It gets ran through computeWorldMatrix, decompose, and inverse multiplyToRef, another decompose.

It all most likely is just float error.

Let me spin up my local and put in some breaks to see what it says each step of the way.

Sorry for so many not even on topic posts before hand (I guess it helps to read before you open your mouth), I deleted them to kinda prevent confusion

And to answer your question about the ignoreNonUniformScaling I would assume it would do just what it says and so would prevent that in the future, but I don’t see any reason why you could not toggle it on and off.

Also the scaling difference is very very minimal and no user would ever really notice it and its never going to really affect any of your scenes unless you are needing some sort of crazy scientific accuracy. If you are worried about it though, you could always clean up the values after the setParent function is ran and just round them .0000000# is quite a small number.

Yeah, well, thanks, I’ll mark it as a solution then.

I’m going to round the scaling vector values after setParent, as using ignoreNonUniformScaling for this would be a hacky workaround.

Cheers!

We can maybe add a argument to toggle it on that method?

https://doc.babylonjs.com/how_to/parenting

not sure an argument would help

I’ve updated the PG (https://www.babylonjs-playground.com/#FQB791#3), now it shows in the console that after setting a new parent, material of the mesh is recompiled (it shouldn’t imo):

Sphere scaling before setting parent:  (3) [1, 1, 1]
Sphere material compiled times: 1
Sphere new parent: box
Sphere scaling after setting parent: (3) [1, 1.0000000385074872, 1.0000000385074872]
Sphere material compiled times: 2