Search Unity

Question Rotate normal Map

Discussion in 'Shader Graph' started by lordzeon, Jul 23, 2019.

  1. lordzeon

    lordzeon

    Joined:
    Jun 1, 2018
    Posts:
    44
    Hi, i need to rotate a normal texture in the Z axis from shader graph, but as expected, the lighting information is not rotated, i´ve tried to use unpack normal and rotate that along axis 0,0,1 but i think the result is not correct. What is the correct way to do a normal map rotation?
     
    Last edited: Jul 23, 2019
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    There's no need to use the unpack normal node, if you set your Sample Texture 2D node to be the Type > Normal and Space > Tangent, it's already doing that. Now, like mentioned in the non-Shader Graph thread on rotating normal maps within a shader, you need to rotate the UV, then counter rotate the normal vector by the same amount. For Shader Graph I would do it like this:
    upload_2019-7-23_23-26-31.png
     
    Lex4art and Juancahf like this.
  3. lordzeon

    lordzeon

    Joined:
    Jun 1, 2018
    Posts:
    44
    Hi Bgolus, thanks for answering, i´ve tried that approach, even copied it exactly to be sure (although i had to change Rotate Node for Rotate around axis because the result was a crazy color cycle.

    The problem, im thinking is that the normal image doesn´t have enought information to reconstruct the lighting correctly in other angles, my understanding of normals is basic, if blue is front, red is horizontal and green is vertical, unity is discarting red and green channel when the texture is set as Normal Type:
    normal-unexpected_normal_base.jpg this map convert to this -> normal-in_unity.jpg
    (scale is different because of export, not a problem)

    when rotated like the above example, the Red and green channels sometimes takes over the blue channel, i tried to substract it, but the result is always incorrect, even rotating round axis Z and splitting and combine with the original map, eventually, blue channel convert to red and green.... this is a example, painting over another texture in a plane and rotating the texture to match the angle from center:
    normal-unexpected_lights.jpg normal-unexpected_normal.jpg
    with lighting normals
    i don´t understand why, if only red and green channels are being rotated (like a Z rotation), normal looks like is being rotated around X or Z...
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    Okay, a couple of things to go over here.

    Yes, blue is "towards" you, red is horizontal, and green is vertical. For Unity, it should be greener on the "top", and that normal map is greener on the "bottom". Unity uses what's known as a +Y normal map, or OpenGL style, where as that normal map is -Y, or Direct3D style. That's easily solved by opening up the image in your 2d image editor of choice and flipping the green channel (assuming your image editor of choice has the ability to modify individual color channels, like Photoshop or Gimp). Having the normal map be in -Y format will lead to some very weird results in the lighting where rotating the object or the normal map can make it look like the normals are spinning in both direction.

    Next bit, when Unity imports a normal map it handles it in a couple of different ways depending on the image compression format used. Generally speaking, for PC & console, Unity throws away the blue channel and only keeps the red and green, but may move those channels around such that the red channel of the original image is stored in the alpha of the texture. This is true for uncompressed, DXT5 or BC7 formats. For BC5, a compression format created specifically for storing tangent space normal maps, the R and G channels are left alone, but that's because BC5 only has red and green, it has no blue or alpha channels. The reasons for this I've explained elsewhere and won't go into here, but the important thing is ... if your normal map is showing as only blue and "R8G8B8A8 UNorm", something has gone horribly wrong. Can you post a screenshot of that image's texture import settings, because something isn't set right someplace?

    Backing up a bit:
    The rotate around axis node does work, though it should be noted it rotates in the opposite direction from the Rotate node. It's also "more expensive" in terms of the amount of shader code it uses, but most likely it'll compile down to nearly the same cost if the shader compiler does it's job well. Just don't put the Negate node in and put the same rotation value into both.

    As for the crazy color cycle, that probably has more to do with the above issue of something going weird with the texture import.
     
  5. lordzeon

    lordzeon

    Joined:
    Jun 1, 2018
    Posts:
    44
    Yes, i know the texture have the Y inverted, but im doing that in another shader transformation (there are a few), just for testing purposes, i will be changing that on final texture imports

    maybe i explain wrong, that blue image is what unity do with the shader after converting that particular texture in rotation 0, i suppose there is a threshold where 45º red and green (because of the texture pattern) is not enought to see any green or red, when rotated 45º red shows correctly, but after that... i don´t think it is correct
    normal-red_channel_0degree.jpg normal-red_channel_45degree.jpg normal-red_channel_135degree.jpg
    0 45 135 (why red is so strong there?)
    my import settings:
    normal-import.jpg
    important note: if i change the type to normal, the texture asset completely break, no more inspector, i can only delete and reimport, this is the original normal map (but i have the same issue with every texture, png or jpg)

    good to know, although performance is not a problem right now for this.
     

    Attached Files:

  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    That texture has not been imported as a normal map, that’s certainly going to be part of the problem. It’s not required that you import the texture as a normal map, but you do at least need to disabled sRGB. That’s going to add a significant bias to the unpacked normal direction as the 127/255 red and green values for a “flat” normal map are going to be sampled as 0.212 rather than “0.5” (really 0.498), skewing it down and left. For an unpacked normal that’s going to mean a value of roughly (-0.42, -0.42, 0.6), which will appear as that solid blue you’re seeing, and explain the rainbow of colors you get when rotating.
     
    Last edited: Jul 24, 2019
    lordzeon likes this.
  7. lordzeon

    lordzeon

    Joined:
    Jun 1, 2018
    Posts:
    44
    I wish to know a bit of what you know, that indeed was the problem!
    thank you thank you thank you thank you thank you thank you thank you !!! i could never figured it out without your help
     

    Attached Files: