Why doesn't normalScale affect material when normalMapType = ObjectSpaceNormalMap?

Is there a technical reason? If so, any explanation or recommended readings would be much appreciated

1 Like

Is there a bug that occurs, does the scene render, does the material render… if not, console.log some of your stuff… I messed around with that stuff a little while back and the three js examples and console.log() saved me

I’m not sure why normalScale does not affect object space normal maps. I think it’s worth to file an issue at GitHub so we can clarify this topic.

The shader chunk works like this:

  • for tangent space it uses the normal scale
  • for object space it uses the normal matrix

Should the normal scale is applied to object space normal map, it has to be a scalar or Vector3. It is hard to imagine how the current Vector2 type of the scale should affect a 3D normal vector.

An extract from normal_fragment_maps.glsl.js:

#ifdef USE_NORMALMAP_OBJECTSPACE
	...
	normal = normalize( normalMatrix * normal );
#elif defined( USE_NORMALMAP_TANGENTSPACE )
	...
	mapN.xy *= normalScale;
	normal = normalize( tbn * mapN );
#endif
1 Like

Oh, I have not answered this. I’m not one of the Three.js developers, so this is just a guess:

  • for tangent space, the X/Y components (tangential) of a vector from the normal map is scaled, while the Z component (normal) is not. So, scaling with a normal scale changes the X/Y size, and keeps the Z size, as a result the vector changes direction and “rotates”. When the scale factor is small, the vector rotates toward the normal vector – thus the effect of the normal map is decreased. When the scale is big, the vector becomes close to the tangent and the effect is increased. See the illustration:
    Untitled Diagram

  • for object space the vector is 3D, so scaling with a scalar will not change its direction (because it will be normalized too). Scaling with a vector will change the normal vector … but it will also change all other normal vectors in a bad way. Thus, if this scaling works for one side of the object, it will destroy the normal vectors on other sides – so 1D scale makes no difference, 2D scale cannot be applied, 3D scale has no good effect

Again, this is only a guess. If you want to scale the normal effect in object space, the normal vectors should go away from the true normal vector of the surface … but this is exactly what tangent normal map does.

2 Likes

@PavelBoytchev Ah thank you so much for the thorough explanation! I feel like this also helped me better understand tangent vs object normal maps in general

@Mugen87 looks like everything works as intended based on this explanation, I can still open a GitHub issue if you think it’s worth having this clarified in the three.js documentation for future readers