mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
101.82k stars 35.31k forks source link

Strange "cut" on a surface caused by normal mapping #1647

Closed ZanQdo closed 11 years ago

ZanQdo commented 12 years ago

This strange seam or cut appears in the back of the neck in this character

http://3developer.com/tmp/normalseam.png

Live model can be seen here

http://p3d.in/AcZ77

The shadeless version shows no seam, and there isn't any edge crossing that part

http://p3d.in/AcZ77/wireonshadeless

alteredq commented 12 years ago

As far as I understood, this may be because normal mapping can be done in a different ways.

If you create a model in one way and then render it in a different way troubles may occur.

http://wiki.blender.org/index.php/Dev:Shading/Tangent_Space_Normal_Maps

The shadeless version shows no seam, and there isn't any edge crossing that part

Quads are just three.js abstraction, WebGL doesn't support quads. Seams there are probably where quads are tessellated into triangles.

alteredq commented 12 years ago

So finally I found a bug in quad tessellation in geometry.computeTangents.

There is still some seam after fixing this though it's much less jarring.

ZanQdo commented 12 years ago

We have now ported your fixes to the engine. However the seam is very noticeable still!

http://p3d.in/AcZ77

Also, specially interesting that our user swears the seam was not present in the old engine (r43) so humf.. something fishy still?

mrdoob commented 12 years ago

I don't see any seam on this one:

http://p3d.in/ntXwj/subd

Cleared cache?

ZanQdo commented 12 years ago

Hi mrdoob, this normal map seam is not to be confused with the subdivision surface related bug, that one is gone now!

However even in the horse the normal map cut can be seen. See this screenpic using the same link you gave me

http://3developer.com/tmp/horse_normal_seam.png

Now back at the bull model where the error is more easily noticeable. This is how it used to look before the fix mentioned in this article:

http://3developer.com/tmp/normalseam.png

And this is how it looks after the fix:

http://3developer.com/tmp/bigred_seam.png

thanks!

alteredq commented 12 years ago

I don't know what to do about this, there were tons of changes since r43 :S

It's possible we are hitting issues I mentioned in the first comment.

Seams in normal mapped models are very common problem and as far as I understood the only solution is to have very tight pipeline where what's happening on the model creation side is exactly mirrored on the shading side (tangent spaces and quad tessellations must match).

Which is kinda hard to achieve for application like yours where models can come from anywhere.

The other "solution" what games tend to do is simply to hide UV seams in less noticeable places, which is also something you can't do.

SHVV commented 12 years ago

I've also faced with this issue and solved it.

Looks like there is a problem with shared vertices on UV seams. In geometry it is one vertex with one position and one normal, but in UV space it must be two (or more) vertices. So, when tangent is computed in this vertex, three.js adds up completely different tangents into one and gets strong visible seam.

To solve this problem, I've split geometry into parts by UV seams (function geometry_splitByUV in example), and they are gone, because after this, each vertex with different position/normal/UV has its own unique tangent.

See this in action: Original: https://dl.dropbox.com/u/5549473/three.js/rock_seam.jpg https://dl.dropbox.com/u/5549473/AIM/rock1_seam.xhtml

After fix: https://dl.dropbox.com/u/5549473/three.js/rock.jpg https://dl.dropbox.com/u/5549473/AIM/rock1.xhtml

hnsr commented 11 years ago

Just wanted to add that I still seem to be getting this issue with r56. I have a simple spherically shaped mesh (an asteroid) consisting of only tris with a tangent-space normalmap that renders correctly in other test programs but when rendered with three.js there are discontinuities along the UV seams. The geometry_splitByUV() fix that SHVV posted does seem to fix this (after making it work with r56, it wasn't using Vector2s for the UVs)

WestLangley commented 11 years ago

@hnsr Can you please make a new post and provide a simple live test case?

See https://github.com/mrdoob/three.js/blob/master/CONTRIBUTING.md