Search Unity

UnpackNormal(fixed4 packednormal) role ?

Discussion in 'Shaders' started by kev42100, Aug 18, 2011.

  1. kev42100

    kev42100

    Joined:
    Apr 17, 2010
    Posts:
    61
    Hello !

    I really don't understand the UnpackNormal( ) function...
    Let-alone the code inside "UnityCG.cginc" ...

    Code (csharp):
    1.  
    2. inline fixed3 UnpackNormal(fixed4 packednormal)
    3. {
    4. #if defined(SHADER_API_GLES)  defined(SHADER_API_MOBILE)
    5.     return packednormal.xyz * 2 - 1;
    6. #else
    7.     fixed3 normal;
    8.     normal.xy = packednormal.wy * 2 - 1;
    9.     normal.z = sqrt(1 - normal.x*normal.x - normal.y * normal.y);
    10.     return normal;
    11. #endif
    12. }
    13.  
    Thanks in advance !
     
    HyunMok_Moon likes this.
  2. niosop2

    niosop2

    Joined:
    Jul 23, 2009
    Posts:
    1,059
    Unity stores its normal maps as DXT5nm, where only the G and A channels are used (because they have more bits available).

    Code (csharp):
    1.  
    2. normal.xy = packednormal.wy * 2 - 1;
    3.  
    Takes the x from the A channel and the y from the G channel, then converts them from the 0 to 1 space to the -1 to +1 space.

    Code (csharp):
    1.  
    2. normal.z = sqrt(1 - normal.x*normal.x - normal.y * normal.y);
    3.  
    Reconstructs the z value from the x and y values since the z isn't stored in the normal texture.
     
    Last edited: Aug 19, 2011
    Andy-Korth likes this.
  3. kev42100

    kev42100

    Joined:
    Apr 17, 2010
    Posts:
    61
    Thanks for the answer but it's hard to understand ... Do you have some links/papers in order to improve my skills on this subject ?
     
  4. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Last edited: Aug 18, 2011
  5. Martin-Kraus

    Martin-Kraus

    Joined:
    Feb 18, 2011
    Posts:
    617
    It should be noted that "packednormal.wy" is exactly the same as "packednormal.ag", it's just another way of writing it.

    I wrote an explanation here: http://en.wikibooks.org/wiki/GLSL_P...ing_of_Bumpy_Surfaces#Normal_Mapping_in_Unity
    (And I have a professional interest in it being understandable; thus, I would appreciate comments.)

    Also note that the motivation for using only two components in OpenGL is somewhat different from what Farfarer has described: in OpenGL Unity might use a two-component texture which actually offers only two components A and a color component, which can be accessed as R, G, or B.
     
  6. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Huh, I didn't realise OpenGL did different stuff. Interesting. What texture compression does it use?

    The swizzled DXT5nm stuff is for improved compression quality.
     
  7. Martin-Kraus

    Martin-Kraus

    Joined:
    Feb 18, 2011
    Posts:
    617
    I wasn't aware of it, but apparently OpenGL 4 supports its own compression format (see appendix C in the specification: http://www.opengl.org/registry/doc/glspec42.core.20110808.pdf ). In OpenGL ES the supported compression formats depend on the GPU.

    However, in OpenGL you can always ask for a two-component texture format with (for example) 8 bits per component. Thus, the driver could use, for example, 2*8=16 bits per texel. In that case, you have to store one of the components in the alpha channel and therefore you have to do some swizzling, too. Thus, I wasn't surprised to see it.
     
  8. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Oh, very cool. So it's smaller than DXT5 (16bits as opposed to 24) and with better fidelity. Wish DDS could do the same thing :p
     
  9. Martin-Kraus

    Martin-Kraus

    Joined:
    Feb 18, 2011
    Posts:
    617
    Doesn't DXT5 use 8 bits per pixel? (That's what wikipedia says: http://en.wikipedia.org/wiki/S3_Texture_Compression#DXT4_and_DXT5 : 128 bits per 16 pixels = 8 bits per pixel)
     
  10. niosop2

    niosop2

    Joined:
    Jul 23, 2009
    Posts:
    1,059
    It is, but it's lossy compression. The 16 bit per pixel format he was talking about is uncompressed, so you save 33% of the size with no quality loss.
     
  11. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    DXT gets 5:6:5 for R:G:B
    DXT5 is 5:6:5:8 for R:G:B:A

    So with DXT5, only the alpha channel remains uncompressed (hence the swizzling with the normal map - uses the G and A channels because they're least compressed).
     
  12. Martin-Kraus

    Martin-Kraus

    Joined:
    Feb 18, 2011
    Posts:
    617
    Errrrrr ... OK. Do you have any references that support this claim?
     
  13. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
  14. Martin-Kraus

    Martin-Kraus

    Joined:
    Feb 18, 2011
    Posts:
    617
    Last edited: Aug 19, 2011
  15. niosop2

    niosop2

    Joined:
    Jul 23, 2009
    Posts:
    1,059
    Oh, it's definitely compressed, it just doesn't use bit reduction and stays at 8 bits, unlike the RGB channels which are reduced to 5/6/5 respectively.
     
  16. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Ah, yeah, uncompressed was the wrong phrase to use. Substantially less compressed would be a better description :p