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

enter image description here

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.

enter image description here

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.

enter image description here

| improve this question | | | | |
  • \$\begingroup\$ Looks suspiciously like the normals on at least one side are inverted (times -1). \$\endgroup\$ – Peter Mar 30 '17 at 22:25
  • \$\begingroup\$ @Peter Do you think its a problem with bad tangent calculation, or with the vertex_normals? \$\endgroup\$ – Charlie Mar 30 '17 at 22:40
  • \$\begingroup\$ @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... \$\endgroup\$ – Peter Mar 30 '17 at 23:25
  • \$\begingroup\$ 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? \$\endgroup\$ – DMGregory Mar 30 '17 at 23:38
  • \$\begingroup\$ @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 \$\endgroup\$ – Charlie Mar 30 '17 at 23:46

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

no more seams !

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.

enter image description here

| improve this answer | | | | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.