NME generates invalid GLSL

Hi,

I have a nme material that generates invalid GLSL shader code. This is the material: Babylon.js Node Material Editor

It calculates the reflection in the vertex shader but it wants to do it before the worldnormal variable is created. This results in a normalize() call without any arguments.
I also have this variant of the shader, which should functionally be the same: https://nme.babylonjs.com/#8GBF2X#1
This however results in it wanting to use an output5 variable before it’s declared.

This is a GLSL output snipped of the incorrect code:

v_output6 = output6;
#ifdef REFLECTIONMAP_SKYBOX0
positionUVW = position.xyz;
#endif
#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED0) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED0)
directionW = normalize(vec3(u_World * vec4(position.xyz, 0.0)));
#endif
#if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)
                vec3 reflectionVector = vec3(reflectionMatrix * vec4(normalize(output5).xyz, 0)).xyz;
                #ifdef REFLECTIONMAP_OPPOSITEZ0
                    reflectionVector.z *= -1.0;
                #endif
                vEnvironmentIrradiance = computeEnvironmentIrradiance(reflectionVector);
            #endif
vec4 worldPos = output6;
mat4 view = u_view;
#include<shadowsVertex>[0..maxSimultaneousLights]

//World position
vec4 output3 = u_World1 * vec4(position, 1.0);

//Reflection texture

//World normal
mat3 u_World_NUS = mat3(u_World2);
#ifdef NONUNIFORMSCALING
u_World_NUS = transposeMat3(inverseMat3(u_World_NUS));
#endif
vec4 output5 = vec4(u_World_NUS * normal, 0.0);

Obviously, it also doesn’t work if I try to use the exported NodeMaterial code.
Is there a workaround I could use for now? Manually fixing the glsl and using that doesn’t seem like a great option since I’m not sure what all the uniform should be set to.

To narrow it down a bit, the following also does not work: https://nme.babylonjs.com/#8GBF2X#2
So it seems that the ReflectionBlock generates the invalid code.

This leads me to believe that this code is not working correctly: Babylon.js/pbrMetallicRoughnessBlock.ts at master · BabylonJS/Babylon.js · GitHub

It’s a bit counterintuitive, but you must use the same World matrix block that you use for the vertex shader (to compute WorldPos) when you compute the world normal!

This will force the system to generate the code for the normal before the code in the Reflection block needs it.

That’s a bit awkward but I don’t see any other solution…

I’m pretty sure I’ve also tried that. I’ve had all the duplicate nodes removed and that has resulted in the situation with the normalize() without a parameter code.

The fix makes https://nme.babylonjs.com/#8GBF2X#2 work, and I could not get your other NMEs to fail by setting a texture on the env block in the NME. Can you provide a link to material that fails even with the fix I mentioned above?

1 Like

You are right, that is indeed the solution. When removing all duplicate nodes I missed one.

It does make things less readable but it’ll do for now. It would be great if something like the reroute nodes from ue4 were a thing, that would help make the spaghetti a little bit more manageable.

Thanks!

You can do ALT+left click on a link to create a node and improve the layout:

Wow, didn’t know that was a thing. Very helpful, thanks!