Search Unity

Hand draw normals

Discussion in 'Shaders' started by RepoGames, Jul 10, 2017.

  1. RepoGames

    RepoGames

    Joined:
    Apr 15, 2016
    Posts:
    69
    Hey
    I want to create a sprite that has 2 walls.
    Untitled31231.png
    Left reacts as if it was facing left, and the right reacts as if it was facing right. So if i put the light on the left the left wall shines and the right is black.

    To do it all I need to do is to create a normal map. So I want to put the normals on the left wall to the left and
    on the right wall to the right like this:
    Untitled444.png .
    But I have no idea how to color it in program like paint. I know unity messes up with Z facing top,
    and the further conversion to normal map from simple texture.

    I thought about setting the color for left to (0,0.5,0.5) (as the wikipedia says) because the normals cant have negative value but it doesnt seem to work.

    Any idea?
     
    Last edited: Jul 10, 2017
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    A normal vector to the left would be a value of:

    (-1.0, 0.0, 0.0)

    The conversion from normal vector to normal map would be vector * 0.5 + 0.5 should would make that:

    (0.0, 0.5, 0.5)

    So the value you got from Wikipedia is correct. In a graphics program that color would be #007f7f, and to the right would be #ff7f7f. If those aren't working I suspect it's something you're doing in Unity that's causing the problem. Either you're not setting the texture to be a normal map, or you left "Create from Greyscale" checked, or you're using the standard shader which is going to do odd things with normals perpendicular to the view direction, in which case using the normals -0.707, 0.0, 0.707 (#257f5a) and 0.707, 0.0, 0.707 (#da7f5a) which are 45 degree angles to the left and right might serve you better.
     
    Last edited: Jul 10, 2017
  3. RepoGames

    RepoGames

    Joined:
    Apr 15, 2016
    Posts:
    69
    Thank you for your response. It really seems to work, but the problem is my normal Z is inverted. Wiki says (0.5 ,0.5, 1) looks into the camera but in my program for some reason they are pointing in the opposite direction of camera so i have to multiply it by (-1) .. no idea why. I use UnpackNormalsScale function

    Code (CSharp):
    1.  
    2. float3 normalDirection = UnpackScaleNormal(tex2D(_NormalMap, i.uv), 1.0);
    3. return float4(normalDirection,1.0);
    4.  
    And its black but should be blue according to :
     
    Last edited: Jul 13, 2017
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    The code you posted should absolutely return a blue color, assuming you're using a texture with 128, 128, 255. The default texture property "bump" I believe is 127, 127, 255 (128 vs 127 are both equally correct / wrong since 0.5 can't be perfectly reproduced, 0.5 = 127.5 / 255). If you're actually getting black I would suspect you're doing something wrong with your texture asset or not actually assigning it to the material.

    If you're using the "-90 degree left, 90 degree right" texture, the left side should absolutely be black since the value that comes out of UnpackNormal is effectively (-1, 0, 0) when the normal map is using 0/255, 127/255, 127/255.

    BTW, in Unity (and in every engine I've worked with, honestly), blue=255 == z=1, not -1. I've never, ever seen blue 255 mean -1. So, honestly I'm a little confused by that assertion. There's an old graphics programming quote for when debugging a problem you need "an even number of sign errors", that is to say when you don't fully understand what's happening you just start adding and removing negative values until things work out. I suspect whomever wrote that Wikipedia article originally was conflating view or world space normals and and tangent space normals, and was using the hack of inverting the Z to get them to match up to their expectations not realizing that flipping that sign was in effect a tangent to view transform.
     
    Last edited: Jul 13, 2017