Home Technical Talk

Hard Surface Normal Maps

polycounter lvl 11
Offline / Send Message
leechdemon polycounter lvl 11
(First off, I've read just about every Normal Map tutorial out there, and either haven't found the solution, or haven't seen the one cause of this problem. So if your response to this is a tutorial, please, tell me specifically what it is you're referring to.)

My overall situation is, I'm Hard-Surface Modeling a large number of cars and baking my normals to a low poly car (around 8k, average)(#A, #B). The issue that I'm having is that my UV Chunks have to have their corresponding geometry split, and so I'm getting seams (#C). Since I'm modeling cars, I'm using each body panel as it's own UV Chunk, so the seams are between the body panels. While this means that you can't see the actual seam, the splitting of the vertices is creating a gap that I can't bake out, and so the body panels themselves are being lit slightly different from each other (#D). This doesn't exist in the high poly mesh; it seems to be entirely caused by the splitting of the geometry (which we're doing in order to get 1 UV coordinate per Vertex so that it looks right in our engine. If there's another way to do THAT...). The splitting is similar to the smoothing group issues listed on Ben Mathis's site (http://www.poopinmymouth.com/tutorial/normal_workflow.htm).

Since the seams are on largely flat surfaces, it shows fairly easily. One idea was to keep as many of these chunks together (front door, back door, etc) so that you notice the problem on less areas, but that doesn't seem like a good overall solution. Plus, most body panels are in weird spots; the quarter panel is usually on the same side as the bumper, etc. The body panels themselves never have seams on corners, always on flat surfaces. The other idea we had was to model a very small body panel into the low poly model, that way the seam would be at a 90 degree angle from the viewer, and wouldn't be lit anyways. This'll be harder to bake, but may or may not help overall. It also seems much more complicated than it needs to be.

Any advice anyone can give would be greatly appreciated. Thanks in advance!

Replies

  • CheeseOnToast
    Offline / Send Message
    CheeseOnToast greentooth
    First off, what software are you using? If it's Maya, you can solve this problem by averaging the normals of the low poly on those verts which occupy the same world space but are part of different mesh chunks (aka shells). Ths will make the low-poly appear to be seamless, and a normal map generated from this will look correct. I don't know how to replicate this in other software, but you should be able to at least copy and paste normals from one vert to another. To be honest though, you shouldn't have to break your low-poly mesh into pieces as you described, unless you're trying to make the car destructable.

    It's an exporter problem which needs to be fixed by the coders. I know verts can only hold one UV co-ordinate each, but that should be invisible to the artist. Every modelling package and exporter I've used can handle UV borders without *appearing* to create multiple vertices, even though they really are there "under the hood".
  • cw
    Offline / Send Message
    cw polycounter lvl 17
    verts can only hold one UV co-ordinate each
    I'm not sure this is entirely correct. It is dependent on the engine how many UVs are in the vertex format. :)
  • leechdemon
    Offline / Send Message
    leechdemon polycounter lvl 11
    cw - The engine we're using only supports 1 UV coordinate per Vert, so in this case he's correct (although I wish he wasn't.... /grumble...)

    Cheese - Sorry, using 3ds Max, should've specified. I can copy/paste normals, but I'm exporting through OBJ, and my exporter regenerates the normals when it writes them, so there isn't much I can do there. We were going to try this through some other formats, but haven't gotten that far yet.

    When I export the object with multiple UV coordinates without splitting them geometrically, one of the two UV coordinates is used in place of all instances of that vertex. So what happens is, one side looks correct, and the first row of polies on the other side of the seam looks horribly wrong. For example, if one vert is at (0.1,0.1), and the other is at (0.1, 0.8 ), sometimes the latter is used, and a gradient across that row of polygons goes from [0.0, 0.8, 0.2] instead of [0.0, 0.1, 0.2]. It's hard to describe, but suffice it to say, everything gets jacked.
  • Av7xrocker97
    why does ben mathis' site show up with like 60 computer threats in norton? It makes me not want to visit his site anymore... O.o
  • CheeseOnToast
    Offline / Send Message
    CheeseOnToast greentooth
    I know there's a few OBJ exporters out for Max...maybe try another one? The format definitely supports user-defined normals.
  • pior
    Offline / Send Message
    pior grand marshal polycounter
    You need to solve one problem at a time.
    You are making clean, hardsurface models. Meaning that you cannot hide anything behind rust or random detail. It means that you need maximum accuracy between what you do in 3d, and what you are exporting/seeing in your game engine.

    - First off, the normals generated by Max using RTT are not compatible with the realtime preview shaders shipped with max (you might have noticed that already). If for some reason you really have to use max RTT, the only way to display the results of it properly in max is to either : Render using scanline and the Renderbump effect ; or, use the 3PointStudios realtime shader with quality mode enabled.

    - Second, you (or your engineers) really need to know the export pipeline perfectly. For instance, even if OBJ can hold vertex normals and UV data properly, some exporters and importers can have flaws and not do the export the way it supposed to be.

    - Third, OBJ does NOT hold tangents data properly as far as I know. Meaning, basing your pipeline around is extremely risky and bound to cause you problems, especially on hardsurface stuff. Plus, some mesh importers/exporters might reset them. You need your engineers to make you tools to display vertex tangents in both your creation app and in the game engine, to make sure that the 'combing' is the same (its hard to explain. You'll understand when you see it).

    Once you solve all this, you'll know that your engine is synched properly to your authoring tool. I know it seems like a big undertaking, and even big studios sometimes skip on this. (Unreal 3 is a great example. Top quality art, but they ran in the same problems.)

    If all fails, simply ask your programmers to implement object space normalmaps. (and come back here if they claim its impossible to use them on animated meshes or rigs). OS will solve all these problems instantly, since they do not rely on the vertex normals and tangents of the lowpoly meshes. Fantastic for mechanical stuff.

    Good luck!!
  • Eric Chadwick
    If you can't change the fact that your engine only supports 1 UV per vertex, then the path of least work may be to edit the vertex normals by hand, and re-bake the normal map.

    1. Select all the low-poly body panels.
    2. Add an Edit Normals modifier.
    3. Select a pair of vertex normals along a panel seam, and press the Average Selected button (make this a hotkey!).
    4. Repeat for each pair of vertices where the body panels meet.
    5. Bake your normal map, export, test.

    OBJ does store hand-edited vertex normals, but your engine might not use them. If it doesn't, talk to your programmers. Implementing this is the least work for them (and you).

    Or you could use object-space normal maps, but beware there are downsides to OS maps.

    (edit... really though, you should get rid of whomever's bad idea it was to limit it to one UV per geom vertex. That's going to cause all sorts of problems. Like, anything cylinder-mapped is going to be split badly.)
Sign In or Register to comment.