Search Unity

  1. Check out the Unite LA keynote for updates on the Visual Effect Editor, the FPS Sample, ECS, Unity for Film and more! Watch it now!
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  4. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

UnpackNormal(fixed4 packednormal) role ?

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

  1. kev42100

    kev42100

    Joined:
    Apr 17, 2010
    Posts:
    44
    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 !
     
  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:
    44
    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