How to maintain high quality normals at different parent scales

Hi Babylon team,

We’re trying to understand why the normals in our scene are looking less accurate if they have a parent that is scaled down.

I edited the playground which is used in the normals documentation to show the issue I’m seeing my changes are from line 44.

How can we maintain the quality of normals regardless of parent scale?

Thanks

1 Like

I think I figured it out. Updated Playground is here.

There are 2 things here. We are using mesh.parent = scaledParent
instead of
mesh.setParent(scaledParent)
The latter will recalculate the normals vector length according to the new scale.

Then there was an issue with normals still looking ‘flat’

In this example the shader has a special input of ‘normalStrength’ which is set to 1.
It needs to be hooked up to the scale factor of the parent.

        // Hook up normalStrength input to scaleFactor
        directX_invMat.getInputBlockByPredicate((input) => {
            return input.name === 'normalStrength'
        }).value = 1 / scaleFactor;

So now it looks OK when it’s under a parent of scale 0.1
image

Now I am wondering, how can we make it so this input block is ‘hooked up’ to the scale value of it’s parent automatically?
I suppose we have to navigate all layers of parents and calculate the scale of them all together.
Is there a better way?

Hello @JezPez , how are you doing?

I believe the problem you are seen has to do with the model matrix changing the magnitude of the normal in the shader. This can be solved by normalizing the normal after the multiplication by the Model matrix.

The following update version of the material should properly handle that:
Babylon.js Node Material Editor (babylonjs.com)

3 Likes

Thanks @srzerbetto We were able to fix it using a normalize shader block in our own shaders.
Once we did that we also realised we didn’t need to change our usage of mesh.setParent() instead or mesh.parent = newParent.

Thanks for your help!