Allow multiple PerturbNormalBlocks in NodeMaterial

PerturbNormalBlock is currently defined as “unique” so you can’t have more than one of them in Node material. I know that this is probably because implementing it would require some refactoring in bumpFragment shaders. (Likely turning some of the code into a function that can be reused)

However, there are multiple cases where you could benefit from 2 normal maps. You might want to have a base normal map and separate “detail” normal map on top of it with smaller scale bumps. Or you might have multiple uvs and a normal map for both. I saw another thread on this forum about merging the normal map values with “NormalBlend” node, but as far as I can tell there is no way to accurately represent same effect as two separately applied normal maps. Or at least I can’t think of how. :face_with_raised_eyebrow:

Luckily for me there currently is just couple of line “workaround” that allows using multiple PerturbNormalBlocks, but it is so hacky that it may break in any future Babylonjs update. So having a proper implementation of non-unique node would be really useful.

Hmm, actually… I may to be figuring the normal map blending out. It looks like I need to take a square root of the “first” normal map “strength” in order to match the “chained twice through perturbNormal” look. :eyes:

EDIT: Hmm… No… Even that doesn’t quite match how strength values behave with actual PerturbNormalBlock… In fact there seem to be fairly major differences for some normal maps.

So I guess multiple PerturbNormalBlock may be the only way to go if you want to 100% match how both normal maps would look individually in the parts where other normal map has neutral value. Back to using the “workaround” for now… :neutral_face:

After some more testing I think it may actually be issue in the PerturbNormalBlock strength factor calculation itself.

Here are some comparisons. PerturbNormal strength 1.0:

Now if I use 0.2 strength it somehow only flattens some of the edges but not others. Leaving a somewhat weird looking result:

If I however lerp with the neutral normal map color using 0.2 gradient and leave 1.0 in the actual strength value it looks much more natural:

So… Maybe the issue is in fact that I shouldn’t be using the strength input at all, and do normal map color interpolation based strength adjustment also when using just a single normal map. That way blending multiple ones remains consistent and apparently even individual normal maps look better. :astonished: