Search Unity

Resolved Normal Unpack missing Z sign

Discussion in 'Shader Graph' started by DekkerC, Oct 24, 2020.

  1. DekkerC

    DekkerC

    Joined:
    Oct 7, 2017
    Posts:
    17
    I generate an image which contains the normals of a terrain. I've read that it's much better to use RGFloat instead of RGB because it takes less data and if we are going to compress it, it will reduce compression artifacts.

    But when I use RGFloats and unpack the normals my z value doesn't have a sign (it's always positive).
    I've tried all settings that I could find and the conversion node. Nothing helps.

    Then I wrote some custom code. It doesn't help either:

    Code (HLSL):
    1. void UnpackNormalWG_float(float4 pPackedNormal, float ignore, out float3 pUnpackedNormal)
    2.     {
    3.         //Make 0 to 1 => -1 to 1
    4.         pUnpackedNormal.xy = pPackedNormal.xy * 2 - 1;
    5.         //Calculate z value
    6.         pUnpackedNormal.z = sqrt(1 - saturate(dot(pUnpackedNormal.xy, pUnpackedNormal.xy)));
    7.     }
    But when I use a RGB texture. My sign is correct.

    Example value: normal = "(0.1063221, 0.9376202, -0.3310046)"
    Or the same value packed: normal = "(0.553161, 0.9688101, 0.3344977)"

    The code that generates the normal of the terrain:
    Code (CSharp):
    1. Vector3 a = new Vector3(0, terrainHeightData[x + 1, y + 1], 0);
    2. Vector3 b = new Vector3(0, terrainHeightData[x + 1, y + 2], pPointSize);
    3. Vector3 c = new Vector3(pPointSize, terrainHeightData[x + 2, y + 1], 0);
    4. Vector3 side1 = b - a;
    5. Vector3 side2 = c - a;
    6.  
    7. Vector3 normal = Vector3.Normalize(Vector3.Cross(side1, side2));
    Does anyone have an idea why the sign is missing from the Z value?
     
  2. DekkerC

    DekkerC

    Joined:
    Oct 7, 2017
    Posts:
    17
    Can't find the thread any more.
    But what I found is that unpacking only works for tangent spaced normal. Not for object or world spaced normals.
    This is because the sign (if the value is positive or negative) of the z value can't be calculated. Only it's absolute (always positive) value.
    In tangent space this isn't a problem as the z value is always positive.