Search Unity

Expanding 2 channel normal maps

Discussion in 'Shaders' started by GaryC, Nov 3, 2010.

  1. GaryC

    GaryC

    Joined:
    Nov 2, 2010
    Posts:
    7
    Hi,

    I have some normal maps which contain only the X and Y components of the vector to save space, thus cutting the normal map down to two channels.

    I believe the way to recreate Z in the shader is : +sqrt(1 – x*x – y*y)

    Can anyone post a line of shader script which achieves this ?


    -Gary
     
  2. Battle Angel Alita

    Battle Angel Alita

    Joined:
    Mar 29, 2010
    Posts:
    44
    Unity is already doing this, when you choise "Texture Type - Normal Map" and "Format - Compressed" in texture inspector
     
  3. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Here's what Unity uses to unpack two-channel normals:
    Code (csharp):
    1. inline half4 UnpackNormal(half4 packednormal)
    2. {
    3.     half4 normal;
    4.     normal.xy = packednormal.wy * 2 - 1;
    5.     normal.z = sqrt(1 - normal.x*normal.x - normal.y * normal.y);
    6.     return normal;
    7. }
    Note that the input is a four-channel DXT5-compressed colour, with X and Y stored in the W and Y components, respectively.
     
    Last edited: Nov 3, 2010
  4. Battle Angel Alita

    Battle Angel Alita

    Joined:
    Mar 29, 2010
    Posts:
    44
    Daniel Brauer
    I prefer to use
    Code (csharp):
    1. normal.xy = packednormal.wy * (255.0 / 128.0) - 1.0;
    instead
    Code (csharp):
    1. normal.xy = packednormal.wy * 2 - 1;
     
  5. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Presumably you'd only want to use that fraction for unpacking if you'd used the reciprocal for packing.

    But why would you want to limit your range like that in the first place?
     
  6. Battle Angel Alita

    Battle Angel Alita

    Joined:
    Mar 29, 2010
    Posts:
    44
    it's because i want to unpack color(128, *, *) to vector(0, *, *), with standart UnpackNormal it will be (0.00392..., *, *)