# Normal mapping soft question: What could this be?

So I'm trying to implement tangent space normal mapping. I bind the uniforms, load the attributes, set the shaders, and out comes this:

This happens on the sides only, and not when in direct light. I'm pretty sure it's matrix related, but could it be I'm mapping the tangent values incorrectly? Has anyone seen something like this before? Or have a hunch what it could be?

UV screenshot, it's a cube, turned into a sphere, and each side is separated. The final object shows no seams on the top or bottom, but rather on each side.

Update: When I order the tangents according to UVs, I get a much cleaner result, but some areas/sides still get an inverted normal. I'm not sure why this is, or how to fix it. It happens on each side, so it is as if the sides get inverted normals.

• Looks suspiciously like the normals on at least one side are inverted (times -1). – Peter Mar 30 '17 at 22:25
• @Peter Do you think its a problem with bad tangent calculation, or with the vertex_normals? – Charlie Mar 30 '17 at 22:40
• @Charlie I'd have to guess. Some of the normals point inside the sphere. If tangent space normal mapping is implemented correctly, that should not be possible. Unless we're looking at double sided triangles and we're actually looking at the back of one of the cube sides instead of the front, because the whole side points in the wrong direction... – Peter Mar 30 '17 at 23:25
• What's odd is that it looks like the artifact interpolates over the span of a triangle - it's not a sharp line like two adjacent triangles using inconsistent basis vectors. So it seems like normals or tangents are being shared across the UV split, rendering a triangle with one vertex in one basis and the other vertices in a different basis. But that shouldn't happen across a UV seam - those should generate separate vertices so each triangle is wholly on one side of the cube or the other with its own basis, no straddling the line. How are you generating your tangents? – DMGregory Mar 30 '17 at 23:38
• @DMGregory Not good enough Im suspecting. Part of this is making a parser, and I think I know where the issue lies. It doesnt solve the lighting not behaving like it should tho :| I'll have a look at it right away – Charlie Mar 30 '17 at 23:46

I found 3 problems, and by solving them, I get this:

A seemingly seamless planet with working shaders. But what is the problem?

The tangents I was generating were mapped to each vertex, in the parser, when in fact, they describe the direction of the normal_map in relation to the UV. Making a tangent per UV value, and indexing them together with the UVs (UV 1,2,3.. and Tangent 1,2,3..) removed the seams, but that was not all.

The second thing I found, was that I was crossing the normal and tangent in the wrong order, when finding the bitangent of vertex_normal/tangent for the tbn matrix, like so:

vec3 n = normalize(normalmatrix * vertex_normal);
vec3 t = normalize(normalmatrix * vec3(vertex_tangent));
t = normalize(t-dot(t,n)*n);  //Gramm-Schmidt process
vec3 bitangent = normalize( cross( n, t ) ); //these were t,n


Which was messing slightly with shadows, but not as much as this:

mat3 tbn = transpose(mat3(t,bitangent,n)); //why transpose??


Apparently I should have been transposing my tbn matrix all along, proving how little of this I actually understand.

Either way, the transpose function is cheap (apparently), and I guess this is the place to call it. I dont quite understand it tbh.