Normal map issue with directional light from backside

Hey all!

I have an issue with the normal map in three.js. Maybe I am doing something wrong please, help me.

I have backed a normal map from the designer, and when I apply it to the material it works fine
But when I add directional light (or spotLight) it causes an issue when light is shining from the back side:

A small video on the test page
There is only one light - directional light looking on a plane from the top, but it goes through the plane and I can see white dots on the back side.
Codepen here:

What is the reason and how to fix it?

Does your plane material have to be double sided?

in codepen - yes, but I also have an issue with Single Front Sided material on the final mesh

Since you are using a flat plane (with no thickness), the glitch could be produced by floating point precision issues. Consider to use a box with a small depth instead.

However, you can’t use BoxGeometry since the material will be applied to all sides. You would have to assign six materials (one for each side) which is a bit clumsy.

It’s probably better to author a geometry in Blender, export it to glTF and then import it via THREE.GLTFLoader.

I have found this issue first on gtlf mesh and then repeated it with the plane in codepen to isolate the issue - normal map + directional light.
I have tried in three.js/editor - the same issue

Also - I have changed the geometry to Box Geometry and updated codepen in first message, the issue is the same Screen capture - f011dc6ae1e9c933acb453fa08b979cc - Gyazo

Hey, @Mugen87, any thoughts? What shall I try?)

Hey, @donmccurdy, I have seen some answers on related topics, could you also take a look at this?

Short summary:
normal map + directional light - works fine when light side, but has artefacts on opposite mesh side.
Codepen here:

I have tried with gltf model from blender and export tangents, but the issue doesn’t disappear

Thank you!

Hey everyone!

Please get your ideas on what I’m doing wrong with this normal map, because I have spent more than a week with this issue and have no ideas at all.

Some additional information:
The model with this normal map was exported from Adobe Substance Painter with default values. I’m not sure, but maybe the normal map itself is incorrect. But how to fix it?
Link to normal map:

I will be happy to any ideas)
Thank you!

I think it would be good to prepare a box with the mentioned normal map and then export it to glTF. In this way, you can easily compare the renderings with different engines. For example the first below viewer uses three.js the second one BabylonJS:

If the glTF asset is rendered differently, it might be easier to find a potential issue in three.js.

Sidenote: glTF assets should be rendered almost consistently by different engines (assuming similar lighting setups).

Hey, @Mugen87,

Thank you for your answer!
I have tried to do some stuff.

  1. Here is the blender file and exported the GLB file ownCloud
  2. Here is how it looks in the blender with Evee engine
  3. This is how it looks in Babylon:
  4. Here is how it looks in three js editor
  5. Here is how it look in gltf viewer by @donmccurdy

You are able to see the issue in all three js and in Babylon. But in the blender with Evee is fine.

In my opinion, the issue is normal map parse fragment shader, because it tries to show light on surfaces that are not in light. But I am not sure.

Any thoughts? :slight_smile:

Hey! @Mugen87, @donmccurdy
I’m wondering if I can do something more to show issue?

In my opinion issue is with all normal maps with high intensity (with high depth).

Sorry, I don’t know how to mitigate this issue…

Have you tried enabling shadow casting?


@gkjohnson You are a genius!

I have tried it before, but maybe I have done something wrong.
I tried again in codepen here a few minutes ago.

AND…!!! It works! I make the shadow camera special “far” parameter not complete. So the bottom corner has still artefacts. So casting shadows fixes this issue!

Thank you!

@Mugen87 Thank you too, your advice helped me to understand the issue too.