Mesh Normal Mapping not working in all directions

Hey guys, I come to you because I am well and truly stumped with the normal mapping not showing up correctly on my dynamically created mesh, but only in the yz-coordinate!
Here’s my steps in creating the mesh:

mesh.Clear();
mesh.vertices = meshData.vertices;
mesh.triangles = meshData.triangles;
mesh.normals = meshData.normals;

The white lines represent my mesh’s normals here.

This is the yz side (the side that cuts through the world x-coordinate). The opposite side looks the same.
The normals are barely barely noticable. It is almost completely flat in appearance.


One more image of the strange smoothness:

The sides from the other coordinates look correct:


One more image of the strange smoothness:

I’ve tried the following with the same problematic results:
-use unity’s mesh.RecalculateNormals() in place of my own method
-compute uv coordinates and replace triplanar shader with unity standard shader
-use different shaders
-remove and re-add mesh rendere and mesh filter at runtime
-changing camera’s rendering paths
-Tried light types Point, Spot, and Directional, in addition to different environment lighting types.

To sum up, I’m completely stumped. Any ideas are welcome! Thanks!

What does your triplanar shader look like? If you’re using a Surface Shader, you still need mesh tangents. If not, then I’d want to know how you’re calculating the world normals from the triplanar normal maps, and how you’re doing ambient lighting.

1 Like

Thanks so much for your response bgolus.

Your link is just what I needed. I’m going to have to give that article a good read!
Sorry I didn’t get back to you sooner, was a long day at work.

My triplanar was using a naive approach I found online, just using the mesh tangents.

Here’s the triplanar normal calclulation:

fixed3 n = max(abs(v.normal) - _Blend, 0);
o.weight = n / (n.x + n.y + n.z).xxx;

uvx = (oPos.yz - _BumpMap_ST.zw) * _BumpMap_ST.xy;
uvy = (oPos.xz - _BumpMap_ST.zw) * _BumpMap_ST.xy;
uvz = (oPos.xy - _BumpMap_ST.zw) * _BumpMap_ST.xy;
fixed3 bz = UnpackNormal(tex2D(_BumpMap, uvx)) * IN.weight.xxx;
fixed3 by = UnpackNormal(tex2D(_BumpMap, uvy)) * IN.weight.yyy;
fixed3 bx = UnpackNormal(tex2D(_BumpMap, uvz)) * IN.weight.zzz;
o.Normal = bz + by + bx;

Until I can get to really diving into the meat of that article, I went ahead and gave Ben Golus’s RNM shader a quick test, and lo and behold!


pure beauty.

Also, thanks for the tip on the surface shader and the mesh tangents. I didn’t realize I needed to be calculating and assigning those. Makes sense though. I knew I was missing something important, but for the life of me I could not figure out what.

Looks like you’ve managed to give me the answers to both of problems in one fell swoop :).

btw, I’ve been helped before by your answers to other people’s questions. Thanks so much for your commitment to the community here!

1 Like

Yep, that Ben Golus guy writes some darn good articles.

  • cough *
3 Likes