NormalMaps+Lighting Issue

(0.94970095, -0.0, -0.31315824) or (-0.9860967, -0.0, -0.1661727)

Actually I realize that the issue comes from the fact that you mapped only half of the model. I’m even surprised that it works so well with just few artifacts. With this kind of uvs, the only way to have proper tangents is to export them along the model. I don’t think recomputing them is possible. I guess that’s how unity manage to do it, because they have them in the fbx.

@nehon said: (0.94970095, -0.0, -0.31315824) or (-0.9860967, -0.0, -0.1661727)

Actually I realize that the issue comes from the fact that you mapped only half of the model. I’m even surprised that it works so well with just few artifacts. With this kind of uvs, the only way to have proper tangents is to export them along the model. I don’t think recomputing them is possible. I guess that’s how unity manage to do it, because they have them in the fbx.

Yeah, the problem is in tangents… But i guess the issue is in the generator… as in blender if i export the model to obj, and then import it again, i see the same normal map. You can make it with my test model either… just export then import it…

I tried to modify a bit tangents of the mirrored part and i havesamoo kind of result. Possibly, you will find the way to fix tangents properly?
Here id the code oof line 515:
[java]
// boolean flippedNormal = false;
for (int j = 0; j < triangles.size(); j++) {
TriangleData triangleData = triangles.get(j);

                tangent.addLocal(triangleData.tangent);
                binormal.addLocal(triangleData.binormal);

                if (givenNormal.dot(triangleData.normal) < 0) {
                    tangent.addLocal(triangleData.normal.negate().mult(0.25f));
                }
            }

[/java]

this code fixes almost everithing.
My fix: http://i.imgur.com/NQG0yRc.png
Without the fix: http://i.imgur.com/z5qtsDq.png

Possibly you will have better idea how to modify mirrored tangents properly…

We cannot apply this change just because it works for your particular model…
For other models it might completely screw up the tangents.

<cite>@Momoko_Fan said:</cite> We cannot apply this change just because it works for your particular model... For other models it might completely screw up the tangents.

Yes you are right. That was like a cheat…

But guys, I found a real solution this time! I had to modify the TBNMatrix of the Vertex Shader and the TangentGenerator. This mix helped me ti fix artifacts. This looks almost like in blender! So here is my new solution. It works for all angles of light without artifacts:

Lighting.vert
[java]
// inTangent.w is applied to wvTangent!
mat3 tbnMat = mat3(wvTangent * inTangent.w, wvBinormal, wvNormal);
[/java]

TangentBinormalGenerator.java:
[java]
// line 515…
for (int j = 0; j < triangles.size(); j++) {
TriangleData triangleData = triangles.get(j);

                if (givenNormal.dot(triangleData.normal) &gt;= 0) {
                tangent.addLocal(triangleData.tangent);
                binormal.addLocal(triangleData.binormal);
                }

                if (givenNormal.dot(triangleData.normal) &lt; 0) {
                    tangent.subtractLocal(triangleData.tangent);
                    binormal.subtractLocal(triangleData.binormal);
                }
            }

[/java]

Ok, now here is my screenshot of different angles: http://i.imgur.com/D7hjVNE.png

@nehon, @Momoko_fan can you review it again. And if it’s ok, so add it to the trunk. :slight_smile:

PS(Edited):
You will need to invert Green(as far as i remember) channel of the Normal map texture. As TBNMatrix was changed.
Or you can make like this:
[java]
// inTangent.w is applied to wvTangent!
mat3 tbnMat = mat3(wvTangent * inTangent.w, -wvBinormal, wvNormal);
[/java]

@mifth - is this a real fix from a sound theoretical base - or is it just poking it with sticks until it works?

Can you explain the reasoning behind the new ones and why it works better?

@zarch said: @mifth - is this a real fix from a sound theoretical base - or is it just poking it with sticks until it works?

Can you explain the reasoning behind the new ones and why it works better?

Yes this is a real fix. With my tests it works ok.
This is fix only for mirrored UVs. If you have a symmetrical model…
TBN matrix should work olike this and Tangents and Bi-tangents should be subtacted for mirrored UVs.
My fix: http://i.imgur.com/D7hjVNE.png
Without fix: http://i.imgur.com/Uar9Qt8.png

No.
First in the fixed screenshot the model on the left still have lighting artifacts, it’s subtle, but it’s still there.
Second you’re completely misusing the parity value (tangent.w) by multiplying it with the tangent. This is supposed to help compute the binormal so that it points toward the good direction. Multiplying it with the tangent makes no sense at all.
I’ll reiterate what Kirill said, it’s not because your model looks better with it that this is a valid solution. You seem to approach this issue with an artist point of view, when this is a pure mathematical issue, we need to find the correct way to compute these tangents, not only that it looks good.

I’m currently digging into Ogre and Blender sources to see how they do it, because we can trust that their way works with a multitude of model types.

1 Like
@nehon said: No. First in the fixed screenshot the model on the left still have lighting artifacts, it's subtle, but it's still there. Second you're completely misusing the parity value (tangent.w) by multiplying it with the tangent. This is supposed to help compute the binormal so that it points toward the good direction. Multiplying it with the tangent makes no sense at all. I'll reiterate what Kirill said, it's not because your model looks better with it that this is a valid solution. You seem to approach this issue with an artist point of view, when this is a pure mathematical issue, we need to find the correct way to compute these tangents, not only that it looks good.

I’m currently digging into Ogre and Blender sources to see how they do it, because we can trust that their way works with a multitude of model types.

Ok, i understand you point. Thank you for reply! Than i’ll wait for another fix. :slight_smile:

Ok now I get exactly what’s going on. the only vertices at fault are the one on the y axis.
There is one vertex, but according to the uv map (as it’s mirrored) it should have 2 different tangent spaces. This means the vertex must be split .That’s how ogre is dealing with it.
This is not as easy as it sounds because until now the tangent binormal generator was not modifying the position buffer.
I guess i’ll make this optional int the generator.
I’ll keep you updated.

3 Likes
@nehon said: Ok now I get exactly what's going on. the only vertices at fault are the one on the y axis. There is one vertex, but according to the uv map (as it's mirrored) it should have 2 different tangent spaces. This means the vertex must be split .That's how ogre is dealing with it. This is not as easy as it sounds because until now the tangent binormal generator was not modifying the position buffer. I guess i'll make this optional int the generator. I'll keep you updated.

You are my hero! Yahoo! Waiting to test it.
Also, Mirroring could be on different axyses… X,Z axys can be mirrored too. Take it into account too.

This issue is fixed in last SVN.
The vertices with mirrored uvs are now split. So proper lighting will come at the expense of few additional vertices.
here are the results on your model. Please test.
This is optional so to test use TangentBinormalGenerator.generate(model,true) (true being splitMirrored).
I intend to go further and split vertices that have very twisted tangent space (they do in ogre), I guess it will fix some more lighting inconsistencies on normal mapped models.
Before (side light):


After :

Before (top light) :


After :

Edit : this guy is really creepy…

4 Likes
@nehon said: This issue is fixed in last SVN. The vertices with mirrored uvs are now split. So proper lighting will come at the expense of few additional vertices. here are the results on your model. Please test. This is optional so to test use TangentBinormalGenerator.generate(model,true) (true being splitMirrored). I intend to go further and split vertices that have very twisted tangent space (they do in ogre), I guess it will fix some more lighting inconsistencies on normal mapped models.

Hi! Lighting looks correctly on both sides. But i found now issue with vertex split.
I downloaded here the TangenetGenerator: Google Code Archive - Long-term storage for Google Code Project Hosting.
My test project: https://dl.dropboxusercontent.com/u/26887202/JME/NormalMapTest_3.zip
Just run Test.java in my project.

Here is my screenshots:
http://i.imgur.com/Lvsn3Ou.png
http://i.imgur.com/MeG7rvH.png
http://i.imgur.com/5mZNLa0.png

PS: This creepy guy helps us to fix all issues. :slight_smile:

@nehon said: This is optional so to test use TangentBinormalGenerator.generate(model,true) (true being splitMirrored).
dude please read. you have to pass true. You're still generating the old way.

The artifacts are worst than before though. I know why, I’ll make it work as before…even if it was wrong.

@nehon said: dude please read. you have to pass true. You're still generating the old way.

The artifacts are worst than before though. I know why, I’ll make it work as before…even if it was wrong.

OOOOhhhh!!! Sorry me please! I have missed that. Now it works super cool! no any rtifacts!
Thank you a lot!!!

@nehon said: dude please read. you have to pass true. You're still generating the old way.

The artifacts are worst than before though. I know why, I’ll make it work as before…even if it was wrong.

Can you also add this option to SDK? When i click rightClick->Tools->Generate Tangents.

oh btw I did add the option in the sdk and forgot to mention

3 Likes