Home Technical Talk

converting local to tangentspace normalmaps

polycounter lvl 20
Offline / Send Message
CrazyButcher polycounter lvl 20
when improving the normalmap support for luxinia, I stumbled upong the problem of normalmap creators using different tangentspaces. Which means if your game doesnt use the same you are doomed... well slight errors will occur.
This is mostly an issue for max8 as it uses non.orthogonal tangent space, which is more accurate, but also less gametypical (well for the new stuff probably not anymore either).
Someone had similar problems with max8 and asked on gdalgos, he later found a solution. Use localspace (should be the same for all apps, at worst some channel flipping) and convert it to tangentspace.
I spend the last days to integrate such a tool into a pipeline commandtool, which also converts 3d formats to luxinia's format.

The outcome is pretty useful smile.gif
It also overcomes the problem of using mirroring, which would be a problem in local space, but as they are converted, the issue should be gone.

local2tangent.jpg

The tool uses MESA OpenGL software rendering combined with vertex/pixel shaders and basically renders an ortho view of the mesh in uv space. The shaders take care of the conversion. They are not hardcoded and other shaders could be used. Also use of MESA means its all CPU, so independent of capability of GPU.

the shading of the hipoly and lowpoly might not fully match in the picture, due to me having not much experience with normal maps and setting it up properly, plus the subdivision was higher on rendertime. (and the lights are different). Nevertheless for the hardcase of having a simple hard edged box as lowpoly, it did work well enough.

the next version of the engine itself will actually making normalmapping useful, as last public release is a bit buggy.

The tool is very oldschool commandline, I will integrate a GUI version in the engine, which calls the tool and will handle the command args.
I am so happy it works, cost me some nerves, that I wanted to share wink.gif

Replies

  • EarthQuake
    Are you trying to tell me you've come up with some crazy solution to dealing with hard edged geometry like this without using any sort of extra chamfers on the edges? Its 5am and i cant say i fully understand this thread my good german buddy.
  • CrazyButcher
    Offline / Send Message
    CrazyButcher polycounter lvl 20
    hm maybe, I was actually trying to hunt my problem with max8 tangent normal maps which looked bad ingame (problems at the edges, visible seams on mirrored uv), and this localspace->tangentspace did work for me...
    also i didnt want to write tons of exporters for normalmap creators, so let them use localspace and convert that...

    its not my idea, I just saw that someone else had similar problems on gdalgos-list and he solved it after getting some advice,too, so I went on and did it his way.
  • MoP
    Offline / Send Message
    MoP polycounter lvl 18
    If you compare Max-generated tangent-space maps with ones generated from identical meshes in the Doom3 engine, you'll see subtle differences (I recall Eric Chadwick mentioning something about different bi-tangents on the lowpoly mesh or something?) ... is there any way that some sort of "standard" could be set for how normals are derived and used between meshes? Kinda annoying when you have different viewers and engines, and each one needs a *slightly* different tangent-space map. It'd be better if they were drastically different, but the only difference I can see is slightly more exaggerated gouraud compensation on Doom3 normals as opposed to Max normals.

    Also, would there be any way to change the way Max renders out normals to match those required by a different engine (such as Doom3?)
  • CrazyButcher
    Offline / Send Message
    CrazyButcher polycounter lvl 20
    no unfortunately max doesnt give you access to its tangentspace generator (maybe 9 does but no idea, there have been complaints about it on sparks too). This doesn't mean max cant be used for other stuff, as e.g there exist various commercial tools that also allow baking, but there is no "easy" acces to it.
    and yes it's the binormal. orthogonal systems often compute it out of normal and tagent, to save bandwidth. non-ortho however is slightly more accurate afaik, but requires normal,tangent and binormal to be sent, which likely isnt that much of an issue on latest hardware and bandwidth anymore...
  • Eric Chadwick
    CrazyButcher do you generate the binormals/tangents yourself? We've been hashing lately over how to fix mirror-uv seams and other uv-translation seams, and came up with some hacks around the problem. Nvidia's Mesh Mender only got us so far, we had to add significantly onto it to get decent results.

    I kinda doubt a simple texture format-conversion is going to remove all your shading seams. We've really had to tackle it at the vertex level. And it still isn't perfect, requires some artist input, designing a UV set that tells our algorithm where to put the seams because we can't eliminate all seams, just the major ones (like the face midline).

    Cool idea though, sounds interesting.
  • CrazyButcher
    Offline / Send Message
    CrazyButcher polycounter lvl 20
    I generate tangents/binormals with mesh mender as well. There is not a lot of normalmap useage in my projects so far, so I havent had a lot of testcases, chances are it will haunt me again. Per helps me with some more "production" like models, will see how the tests go with them. However the other coder who originally started the thread on gdalgos said it works fine for them (www.3d-io.com is the company).

    The convertor does require the mesh and all per-vertex attribs, it also needs all mirrored UVs to be of "same side". As the local space normal map of mirrored stuff can of course contain only data for one side, and it is crucial for the conversion that the proper one is chosen. The conversion itself is done on per-pixel level using the same interpolations that would be used on rendering... (thats why MESA is used to resemble 3d hardware shading)

    Though as the ortho space I use is not as accurate as the non-ortho of max or others, I guess issues can arise, at least another coder warned me that ortho space has it issues too. however that wouldnt change the workflow of the method, as any normals/binormals... could be sent.
  • Eric Chadwick
    So how do you handle poles?
  • CrazyButcher
    Offline / Send Message
    CrazyButcher polycounter lvl 20
    and poles refer to what?

    I tested with a noised and deformed box,
    http://crazybutcher.luxinia.de/wip/local2tangent/

    the first screenshots are converted from local , the max ones use the max tangentspace normalmaps.
    to be fair the error must happen as different tangentspaces are used. So for me this conversion is needed to stay somewhat independent from max's way of making tangents.

    however one can also see seams slightly in my converted version, that is due to ortho not as good as non-ortho... but I think with some better and "closer" hipoly mesh (the noised hipoly box was far away at times..) I could hide them a bit better. likely they will never go away... it's a big improvement for me anyway.

    if you are after fixing those small glitches while sticking to ortho too, then thats out of my league and as you mentioned would required more work in tangentspace creation. (but to me it looks as if those issues could be fixed by using non-ortho space)

    btw another code told me to recreate max8's tangentspace have a look at the VNormal.cpp (samples\materials\NormalBump) which is what they use, but means dependency on max8
  • Eric Chadwick
    I meant where you have a difficult binormal situation, like the poles of a sphere. Another problem spot, where you have a seam that in geometry space shares the same line of vertices, but in UV space the two edges are perpendicular to one another.

    Looks like your solution is coming along well. Lighting is an improvement, but still those pesky lines.
  • CrazyButcher
    Offline / Send Message
    CrazyButcher polycounter lvl 20
    are you sending binormal and tangent ? I always thought the main reason of sending both is that it would fix these things ?

    by the way I just thought of another issue, when geometry lines are not same in pixel-length, wouldnt that also mean interpolation runs non-perfect ?
  • Eric Chadwick
    Well, we have to recreate them, we don't export those from Max. We have some cool blending code that apparently requires more intense tangent calculations.

    But anyhow, even if you export the tangents that Max creates, you still have trouble wrapping a 2D flow across a 3D surface. You're going to have to have some seams somewhere on the surface where the tangents don't face the same direction.

    Poles of a sphere are the most obvious example (and most difficult to solve apparently)... what happens to the tangents as you run over the top of the sphere and start heading down to the equator again? Usually all the tangents at the pole face "Up" at the pole, so you get a seam there. Anyhow, not something I worry about, almost never UV that way.

    Hmmm. Think of an arm meeting a torso. How do you solve all the tangents there? If the arm and torso are each treated as cylinders, then the arm's "up" needs to be reconciled with the torso's "up" along their shared vertices (the seam). The tangents there end up quite different.
  • CrazyButcher
    Offline / Send Message
    CrazyButcher polycounter lvl 20
    okay, the tool would still be useful as "normalmap creator" independent way of importing the normalmaps, or ?
    And for fixing the seams this just wont work the way I thought, so my early joy was just a bubble that exploded hehe
  • Eric Chadwick
    Sorry man, heh heh. I guess using as a post-processor might be an interesting step, kind of a way to avoid encoding Max's own vertex normals into the normalmap.
  • CrazyButcher
    Offline / Send Message
    CrazyButcher polycounter lvl 20
    I did numerous tests with that asteroid, and it actually only works well when "local space" is used. tangent space always produces seams, even in max8 viewport (slightly worse than the ones I get).
    The only time max renders them right as well is the scanline renderer. but so far I couldnt find out why. they must be sending some data slightly different than the realtime version..
  • EarthQuake
    [ QUOTE ]
    If you compare Max-generated tangent-space maps with ones generated from identical meshes in the Doom3 engine, you'll see subtle differences (I recall Eric Chadwick mentioning something about different bi-tangents on the lowpoly mesh or something?) ... is there any way that some sort of "standard" could be set for how normals are derived and used between meshes? Kinda annoying when you have different viewers and engines, and each one needs a *slightly* different tangent-space map. It'd be better if they were drastically different, but the only difference I can see is slightly more exaggerated gouraud compensation on Doom3 normals as opposed to Max normals.

    Also, would there be any way to change the way Max renders out normals to match those required by a different engine (such as Doom3?)

    [/ QUOTE ]

    Doom3 uses some sort of hybrid tangent thing that isnt the same as max. Chai has a half-written doc about it here: http://www.svartberg.com/tutorials/article_d3normalmaps/d3normalmaps.html
  • Eric Chadwick
    Good link EQ, thanks!

    gdAlgortihms has a related thread right now, might be worth a read.
    http://sourceforge.net/mailarchive/forum.php?thread_id=30627501&forum_id=6188
  • CrazyButcher
    Offline / Send Message
    CrazyButcher polycounter lvl 20
    thanks EQ ! although it basically wont change the situation as my special asteroid already had smoothing groups equal to UV isles, which is basically the same as they do, but as I wasnt aware that they do it at all, it's a help smile.gif

    Eric I just got the gdalgos batched email-digest today =)

    but basically I hope the stuff I did so far is suffcient for "real world" models and not the extreme asteroid case which I artificially created...
Sign In or Register to comment.