Where does `#define XXX` get added to GLSL code?

I’m using THREE.MeshNormalMaterial and looking at the compiled GLSL code.

When I create the material like this:
mesh.material = new THREE.MeshNormalMaterial();, lines 6&7 of the frag shader are:

#define GAMMA_FACTOR 2
uniform mat4 viewMatrix;

But when I assign a normalMap like this: mesh.material.normalMap = myTexture; it looks like 3 new lines get added to the fragment shader (along many others down below):

#define GAMMA_FACTOR 2
#define USE_NORMALMAP
#define TANGENTSPACE_NORMALMAP
#define USE_UV
uniform mat4 viewMatrix;

Where in the Three.js source code does this take place? I’m trying to figure out where the #define USE_NORMALMAP gets added and the new shader is uploaded to the GPU so I can re-create this behavior with a THREE.RawShaderMaterial. I’ve searched all over the src\materials and src\renderers\shaders folders, but I can’t figure out where this gets added.

WebGLRenderer and it’s dependencies. I’ll look in more detail, but this is generally where three generates GLSL. It’s a bit mind melting, i have empathy for you :slight_smile:

1 Like

I saw your post on StackOverflow that helped me a lot. For now I’m basically doing:

material.defines.USE_NORMALMAP= ''; // If it exists
material.defines.USE_NORMALMAP= undefined;// If it doesn't

The hard part to figure out is what else should be defined when adding each component?

See https://github.com/mrdoob/three.js/blob/d2a4ed6c98a1621df65b7b5081715170add884fe/src/renderers/webgl/WebGLProgram.js.

I typically use SpectorJS to inspect compiled GLSL, then backtrack to figure out what I’m missing that I need, and that a default material would have.

5 Likes

Ah, there it is. Line 584
parameters.normalMap ? '#define USE_NORMALMAP' : '',
Simple as that. Thanks!

And yeah, I love SpectorJS. Don’t know what I’d do without it!

Out of curiosity, have you considered using NodeMaterial for this? It should be a better way to write GLSL than GLSL.

I’m starting to consider it, right after I finish ripping my hair out… :crazy_face:
what does #if 0 > 0 do?

2 Likes

Dunno what its supposed to do, but i know what it does - it melts my mind. Really curious, there’s a 1 > 0 as well.

1 Like

@pailhead Figured it out. I noticed at the end of the vertex shader I was getting a lot of empty if statements.
def
So I looked into the shader chunk that pertained to that segment, and it looks like it’s actually a variable that gets preprocessed into a number literal:
def2
I’m guessing there’s a preprocessing step somewhere that replaces NUM_??_LIGHT_SHADOWS with 0, and that’s how you get all those if 0 > 0 to ignore that section.

Edit: I just found where this replacement takes place. Starts in line 176 of WebGLProgram.js

Ah i thought it might be something like that, since i couldnt find it anywhere in the source. But it didnt occur to me it woul dmake sense with lights.