Announcement

Collapse
No announcement yet.

Multiple Normal Maps on Separate UV Channels?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Multiple Normal Maps on Separate UV Channels?

    Hi,

    I was just testing out some ideas to create a material that would allow me to blend two sets of normals together from separate UV channels on a single asset. The goal was to see if I could achieve something like the little edge chips/cracks seen in the P.T. Silent Hills demo (screenshot below).

    What I was attempting to do is create one UV channel with all my surfaces unwrapped normally with standard UV seam placement for use with a tiling wall texture. On a second UV channel, I would unwrap all the chamfered edge polys and align them in a single direction that could then take a tiling 'worn edges' normal map. I can assign the multiple UV channels with the TextureCoords node in the material editor, but the way the normals plugged into the second UV channel react to lighting is wrong. UE3 had issues with correctly handling lighting direction from normal maps assigned to multiple UV channels, and I was hoping this may have changed in UE4, but that doesn't appear to be the case.

    Attached are a few images illustrating my test setup. Note that I made the bricks fairly extreme just to see what was going on. Also, it's always the second UV channel that experiences the bad lighting flips. If I swap UV channels so the bricks are on UV0 and the tiled rough edges are on UV1, then the rough edges are reversed in odd directions (it's just harder to see in a still image post).

    If this issue with the way normals are handled on a second UV channel isn't something that can be resolved, is there a particularly good way to go about adding a tiling strip of edge decals to corners like the P.T. image below? It's definitely a tiled effect that gets repeated elsewhere, so they're not just using high-res custom models everywhere. Also in particular, note the rounded corner, which isn't conducive to using the standard decal sticker projectors. I'm guessing they have a setup similar to Cryengine, which allows the use of deferred decal materials to be applied to any arbitrary geometry (it just writes whatever material inputs are set in the decal material on top of the rest of the deferred render pass), but that's currently not something UE4 allows (might make a request post later, since it's an insanely useful tool for level art using tiling textures).

    Reference image from P.T.
    Click image for larger version

Name:	10659347_10152698003479479_437453629293825597_n.jpg
Views:	1
Size:	31.3 KB
ID:	1138819

    My test setup:
    Click image for larger version

Name:	TestMesh.jpg
Views:	1
Size:	173.5 KB
ID:	1138820
    Click image for larger version

Name:	Two_UVChannels.jpg
Views:	1
Size:	341.6 KB
ID:	1138821
    Click image for larger version

Name:	LightingFlip.jpg
Views:	1
Size:	323.6 KB
ID:	1138822

    #2
    Yep, you can definitely set a different UV channel for different normal maps and then combine them. It's one way of combining a general normal map with small surface detail

    Comment


      #3
      ...Do you care to elaborate as to how without getting normal/lighting errors? I guess if it wasn't clear reading my first post, here's an animated gif showing how changing UV channel 0 affects the lighting/normals of UV channel 1 in an undesirable way. The second UV channel doesn't change at all (the one where the obvious brick normals are applied) so regardless of what I do to the first UV channel, the second one with the bricks shouldn't be changing at all if this system works the way you're saying it does.

      This obviously isn't the case, however, since the shading and highlights on the bricks shift whenever I alter the first UV channel - even making the bricks look inverted at times when I move the other set of UVs around.
      • UV0 - UVs shown off to the right moving around
      • Arrow texture - mapped to UV0 (the one moving around)
      • UV1 - Never changes
      • Brick normals - mapped to UV1 (lighting should be static, not moving around)



      Last edited by Nick!; 09-25-2014, 09:53 PM.

      Comment


        #4
        I'm not sure if this is the source of your problem, but, as far as I can tell, your normal map is upside down.

        Comment


          #5
          Your UV shells should be arranged exactly the same in both of your UV channels. You answered your own question with your gif - rotating the first UV channel affects how the surface is rendered in engine, and will cause shading errors if your 2nd channel doesn't have the faces oriented in the same direction.

          EDIT: When I say "arranged exactly the same," I mean that you shouldn't rotate them on one and leave them unrotated on the other. If you rotate a face in one UV channel, you must rotate it the same in the 2nd UV.

          Comment


            #6
            No, you should be able to have completely different UV's in your channel and use them the way you want.
            Maybe it's my screen though but it looks like the normal map doesn't look like the right color, are you sure it's using Normal Map compression?
            What's happening there is that the normals of the surface are getting turned around, and that doesn't make much sense. Changing the first UV channel should not effect the normals in any way.

            Comment


              #7
              Originally posted by darthviper107 View Post
              No, you should be able to have completely different UV's in your channel and use them the way you want.
              Maybe it's my screen though but it looks like the normal map doesn't look like the right color, are you sure it's using Normal Map compression?
              What's happening there is that the normals of the surface are getting turned around, and that doesn't make much sense. Changing the first UV channel should not effect the normals in any way.
              Actually, you're wrong. UV Shell direction in different UV channels does affect how normal maps render, in the same way mirrored normal maps do. The engine struggles because you are giving each vertex normal information that is conflicting based on the UV shell direction.

              OP, a simple test I would suggest - map your normal to UV set 0, lightmaps to UV set 1, and your diffuse to UV set 2. That should solve the issue, because the normals will be controlled by set 0 and won't conflict. Hope that makes sense, this worked in UDK but it might not work in UE4.

              Comment


                #8
                Originally posted by MooseCommander View Post
                Actually, you're wrong. UV Shell direction in different UV channels does affect how normal maps render, in the same way mirrored normal maps do. The engine struggles because you are giving each vertex normal information that is conflicting based on the UV shell direction.

                OP, a simple test I would suggest - map your normal to UV set 0, lightmaps to UV set 1, and your diffuse to UV set 2. That should solve the issue, because the normals will be controlled by set 0 and won't conflict. Hope that makes sense, this worked in UDK but it might not work in UE4.
                No, UV direction should not in any way change the effect of a normal map or the normals of the mesh, there's nothing that's tied into that. And certainly there shouldn't be an issue where the first UV channel is effecting what happens on the second.

                Mirrored normal maps have an issue because to be able to mirror the UVs you're flipping the mesh, if you're only rotating a normal map then it's not a problem.

                Comment


                  #9
                  Originally posted by darthviper107 View Post
                  No, UV direction should not in any way change the effect of a normal map or the normals of the mesh, there's nothing that's tied into that. And certainly there shouldn't be an issue where the first UV channel is effecting what happens on the second.

                  Mirrored normal maps have an issue because to be able to mirror the UVs you're flipping the mesh, if you're only rotating a normal map then it's not a problem.
                  You're right! UV direction in different sets shouldn't affect the normal map, but for some reason in Unreal it does. OP even notes that in his initial post. This was a known problem in UE3 and it seems to have carried over sadly. The best way to solve it is use your unique normal map in UV set 0.

                  Comment


                    #10
                    Originally posted by darthviper107 View Post
                    No, UV direction should not in any way change the effect of a normal map or the normals of the mesh, there's nothing that's tied into that. And certainly there shouldn't be an issue where the first UV channel is effecting what happens on the second.

                    Mirrored normal maps have an issue because to be able to mirror the UVs you're flipping the mesh, if you're only rotating a normal map then it's not a problem.
                    This is just unequivocally 100% wrong though, like I'm not sure why this misinformation keeps getting posted when a 5 minute test in the engine itself will show this is factually incorrect. It's the exact issue I posted in the animated GIF above where I put the arrows in UV1 and brick normals in UV2 and rotated only UV1, which resulted in the highlights/shadows shifting around on the unchanged brick normals.

                    The whole reason I can't simply map all the normals to UV1 is for the issue shown in my first post. For large level architecture, there's a need for heavily repeated tiling normals using one UV set, and then another set of normals applied to the corner edges of geometry that require being mapped differently to separate UV set. If these edge textures were only albedo/roughness/metallic/etc. it would work, but as soon as there's a normal in there the whole thing is broken because the lighting is incorrect. Ideally we could just handle the second set of normals with manually-created decals like Cryengine allows and as I ask for in this post (apparently to no avail ).

                    Comment


                      #11
                      I'm going to do some tests and try getting something working with technique tonight, hopefully something quick to set up and has good results. None of the edges where anything is painted looks hard, wish I had P.T. so I could try to break it down more.

                      Comment


                        #12
                        Originally posted by ZacD View Post
                        I'm going to do some tests and try getting something working with technique tonight, hopefully something quick to set up and has good results. None of the edges where anything is painted looks hard, wish I had P.T. so I could try to break it down more.
                        I'm definitely interested if you're able to get something working, but I don't have high hopes without the lighting/rendering/vertex math in the core engine being adjusted in some way.

                        Regarding the P.T. example - that's a pretty subtle use of the technique. Check out the images in my post here (the text is basically irrelevant for what we're discussing here) - the really obvious normal mapped edge cracks are probably a better test scenario.

                        Alternatively, try to replicate the stonework edges from Z-enzyme's post in the same thread (except with normal maps). The only thing I'd keep in mind here that while the stonework in this post could likely survive as a floating set 1-bit alpha masked cards (which would then light correctly), the Cryengine shots in the previous example show the kind of smooth alpha blending that I'd really like to see (which, as it stands in UE4 right now won't light the same as the rest of the opaque geometry).
                        Last edited by Nick!; 07-07-2015, 08:16 PM.

                        Comment


                          #13
                          Nick! is right, the tangent basis is determined by the first UV channel. That is the basis from which the transform is performed when transforming from tangent into world space which is a required step when using tangent space normal maps. The engine actually only stores a single tangent vector. By doing a cross product with the tangent vector and the vertex normal, the other vector (some call it the bi-normal) can be derived without storing anything.

                          So if your normal map UVs disagree with the direction of the base UVs, they will be transformed in the wrong direction (ie if its upside down the G channel will be flipped).

                          That said, you could in theory attempt to bypass the final tangent->world transform and transform into a custom space for another normal channel as long as you impose a rigid structure for the orientation. But that isn't possible for a curve...You may even need to encode the tangent vector into another UV channel using a script for that to work like you want in the 1st arch image.

                          For the non-curve case, you should be able to derive a stable tangent basis using the vertex normal and the material function "Create Third Orthogonal Vector" combined with "Matrix 3x3 Tranform" or possibly "Inverse3x3Transform". But it won't know about the curve so will gradually be wrong until it is 90 degrees wrong at the top of the arch.

                          If you are wondering why Tangent Space normal maps are the standard there is a pretty big reason: Compression!!

                          Local or World Space normal maps can be used, but then they are storing the full curvature of the vertex normals as well which tends to compress poorly. With tangent space, only the difference of the surface from the vertex normals is stored which compresses much better when combined with uncompressed vertex normals.

                          FWIW I have been wanting to do this for years as well. For the most part I worked around it by using floating shell geometry that has the UVs as UV0 etc. But that is way more work than it would be if it just worked with multiple UVs. I just ran into your other post about decal geometry and I am getting some conversations going among the rendering guys. It turns out that idea has been bounced around already and the time may be soon to get something like that scheduled. Seems related to this.
                          Last edited by RyanB; 07-07-2015, 10:04 PM.
                          Ryan Brucks
                          Principal Technical Artist, Epic Games

                          Comment


                            #14
                            Great write up RyanB! I noticed this little hitch a while ago and just figured it was a limitation of tangent space normal maps, but it sounds like it's actually more of an optimization thing.

                            You mentioned that you yourself hoped for this feature in the past....I suppose that means there's a strong reason (performance?) calculating the tangent on uv1 as well is not in the engine and most likely wont be in the future?

                            Great to hear about the geometry decals possibly making their way into the engine someday though

                            Comment


                              #15
                              i'm fairly certain that geometry decals are already possible. not much stopping you from assigning a decal material to geometry

                              Comment

                              Working...
                              X