- Home /
Weird sphere normals???
As u can see from the picture I have a weird problem with normals. I start from a sphere and through a script I displace the verts and once it's all done I call mesh.recalculatenormals. The problem is that once I use a normal debugging shader to this new mesh I just created,I obtain this ugly effect.
Is there a way to fix it?
Thanks
Is it your own sphere mesh?
It looks like some of the verts are split (like for a texture seam.) Thus, recalc normals can't "see" the adjacent face, resulting in those seams in your image.
those 2 spheres are $$anonymous$$e, but the right one was imported from blender, while the other was displaced according to a script, then its normals were modified using the function RecalculateNormals
Owen is right. It's a texture scar. Any amount of mismatch on the sides of a UV map is massively over-pronounced with any amount of masking and image processing, like normal map creation.
I think GI$$anonymous$$P has a function to make textures 'seamless'. Basically makes both sides of the seam match up so you don't get a hideous scar. It's good for some things but for UV of a model mapping it's tricky.
The trick I use, which only works if you are drawing your texture onto a UV map, is to draw slightly beyond the limits of the island edges, if possible. When the normal map is created you wont get hard edges or gulleys etc on the island edges themselves. This means that when you skin your model the bumps gulleys and hardedges are effectively hidden and connecting edges should connect more seamlessly.
Answer by Owen-Reynolds · Aug 28, 2013 at 04:00 PM
After recalcl norms, you should be able to run a pass through the Normal array and hand-average, so all norms on the "same" vert are the same. For real, normals use a weighted average (based on amount of angle of each face,) but for a sphere with all same-sized faces, that won't matter.
The problem is, in the export, and this has to happen and is not a Unity thing, every vert along a texture seam or non-smooth crease is split. Say you have a texture seam along 6 verts. The unwrap has 6 verts on the left, and the 6 split versions on the right, at different points on the texture. If you try any fancy tricks with a merge, you lose that texture data (unless you merge, recalc norms, then unmerge using the old data, which seems a lot more complicated.)
Untested, probably wrong variable names, not very efficient, but hopefully the idea is obvious (averging norms for same verts):
// make sure we don't average 2,5 and 9 over and over:
bool[] done = new bool[verts.Length];
for(int i=0;i<done.Length;i++) done=false;
// check each vert for repeats:
for(int i=0;i<verts.Length;i++) {
if(done[i]) continue;
// look for all verts with same coords:
// prepare to average all their norms:
int dupCount=1; // add "me" to the average
Vector3 normSum = norms[i];
for(int j=i+1;j<verts.Length;j++) {
if(Mathf.approx(verts[i], verts[j]) {
dupCount++;
normSum += norms[j];
}
if(normSum>1) {
// found some copies
Vector3 newNorm = (normSum*(1.0f/dupCount)).normalized;
// assign new averaged normal to all copies:
for(int j=i;j<verts.Length;j++) {
if(Mathf.approx(verts[i], verts[j]) {
norms[i] = newNorm;
done[i]=true;
}
}
}
}
The second loop going from i+1 is an old trick. if 2,5 and 9 are the same, 2 will handle them all (and set done) so you never have to look backwards.
Answer by Jona-Marklund · Aug 26, 2013 at 06:54 PM
The problem is that when you use RecalculateNormals Unity splits the verts at UV seams. One solution to this could be to export the sphere using :
http://wiki.unity3d.com/index.php?title=ObjExporter
Then reimporting it into your 3D modeling application of choice and reexporting it with proper normals again.
Provided that you save the displaced mesh as a model in Unity you could use the import settings to calculate new normals as well as new tangents.
Not sure if that'll give you the result you desire, but it's worth a shoot.
If not then I'm sad to say that I'm at a loss, good luck to you!
Yes, I know how to do it, but it seems a lot of work... I really appreciate your answer, but I am trying to do it through a script, in the quickest way possible
Then the only way I can think of that is left is incorporating an export script into an editor script which reimports and sets all proper flags etc in the editor, seems doable but that'd be a load of work.
Again, good luck to you in your search for an answer, sorry I couldn't help out more.
Best Regards Jona
Your answer
Follow this Question
Related Questions
Why is my shader showing hard edge artifacts on mesh planes? 0 Answers
Strange Error: Shader wants normals, but the mesh doesn't have them 3 Answers
Outlines Defined by Shading Groups? 0 Answers
Shader Color Bumped elements 0 Answers
Render depth seperately 0 Answers