Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

About the normals of merged meshes.

Discussion in 'Editor & General Support' started by Zoodinger, Aug 13, 2013.

  1. Zoodinger

    Zoodinger

    Joined:
    Jul 1, 2013
    Posts:
    43
    Hello all,

    This is my first question here ever. Sorry for the long post!

    The situation: I have a room model that can have up to 4 possible doors (one for each side). When there is no door at the side, I'd like for the model to look closed there. Using my modelling program of choice (blender), I made an extra model which is a wall and closes exactly the gap as it should. This model uses a different area of the same UV texture.

    As you might have already guessed, lighting there does look odd, in a way that makes it obvious the extra wall is a different object. I was expecting that. Merging the shapes improves it somehow, but contrary to my expectations you can still distinguish it even after recalculating the normals. I have even tried using a model of the base room without the faces that would overlap, with the same results.

    Now, if I combine the models via Blender and remove the double vertices, the model looks perfect. Since the room is symmetric in 4 sides, assuming there are no rooms with no doors (because that'd make no sense) and assuming I can rotate but not mirror a mesh, there are really only 6 possible combinations. This isn't much at all; only +4 ~10-20kb models. The programming beast within me, however, growls at this solution, because there could be a time in the future when this solution would not be enough, since I plan to have different environments in the future.

    So, what causes this issue, and how could I fix it? Merging the vertices sounds like a good idea, but won't that screw up the UVs? I assume that when blender exports, it separates a vertex into many if the UV coordinates are different for each face they belong to. But if that's true, then the imported room should be technically identical to the generated one, as it contains exactly the same vertices at exactly the same positions. One possible explanation is that there's some kind of very minor float precision problem which somehow causes the common vertices of the two combined meshes to not be at exactly the same position.

    Finally, in-editor solutions (if any) will not do because I'm using my own custom level editor and so everything is created during runtime in the beginning of each level.

    ~ Zoodinger

    Edit: I did try turning off mesh optimization.

    Edit2: It seems that even though when calculating the normals of imported meshes is correct, recalculating them during runtime produces wrong results even when no other change is done to the mesh. Is that normal behaviour?
     
    Last edited: Aug 13, 2013
  2. porglezomp

    porglezomp

    Joined:
    Aug 21, 2012
    Posts:
    40
    Can I see a picture of what the odd joint looks like? That might help me understand exactly what the problem is.
     
  3. Zoodinger

    Zoodinger

    Joined:
    Jul 1, 2013
    Posts:
    43
    I have actually managed to fix this issue.

    The reason I was confused was that I didn't understand how Unity treats meshes. It uses a different algorithm to calculate normals on import than during runtime, because there's more information available (which is stripped away after the model is imported). Import not only calculates normals, but also combines or splits triangles when it can . Therefore, changing the smoothing angle is not possible during runtime unless you break up the shape into more or less vertices, and even then there's a problem because of the UV coordinates.

    Long story short, I have written a different recalculation algorithm which clusters nearby vertices within a margin and smoothens normals. The result looks correct to me, but I don't doubt that one may still encounter inaccuracy issues (as is the case of dealing with floats). Of course, this algorithm is not only slower than the standard Unity one, but it consumes more memory as well. It's fine for desktop applications, but it might be too slow for mobile apps.

    Code is here: http://ideone.com/QF2ZP5

    Anyone may use it as they see fit. If you have any optimization suggestions you are more than welcome to make them.
     
    Last edited: Aug 13, 2013