Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Graphics.CopyTexture has wired behaviour when I use it to create a Texture2DArray asset

Discussion in 'General Graphics' started by suppertbw, Aug 30, 2023.

  1. suppertbw

    suppertbw

    Joined:
    Mar 16, 2016
    Posts:
    33
    Code (CSharp):
    1. Texture2DArray texture2DArray = new Texture2DArray(texArray[0].width, texArray[0].height, texArray.Count,
    2.             texArray[0].format, false, isLinear);
    3.         for (int i = 0; i < texArray.Count; i++)
    4.         {
    5.             Graphics.CopyTexture(texArray[i],0,0,texture2DArray, i,0);
    6.         }
    I'm using above code to generate a Texture2DArray asset. It's wired when I use it to generate a normal map Texture2DArray asset.

    The asset becomes pink when I preview it.

    The reason I found is that all of data in red channel of every normal map go to alpha channel in the Texture2DArray asset. I've checked every normal map's format, it's BC7. Also I tried to change the format but the issue is still there.

    But, if I change to iOS platform and use ASTC6x6 format for every nomal map, the generated Texture2DArray asset is good.

    I'm confused what happened?

    normal map.png
    Every Normal Map

    upload_2023-8-30_11-7-59.png
    Pink Normal Map Texture2DArray
     
    Last edited: Aug 30, 2023
  2. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    547
    Not entirely sure but my guess is that it has something to do with normal map encoding. I think, Unity uses DXT5nm on PC by default:
    https://docs.unity3d.com/ScriptReference/NormalMapEncoding.DXT5nm.html

    This is how DXT5nm normal maps are decoded (UnityCG.cginc):
    Code (CSharp):
    1. // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1)
    2. // Note neutral texture like "bump" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5
    3. fixed3 UnpackNormalmapRGorAG(fixed4 packednormal)
    4. {
    5.     // This do the trick
    6.    packednormal.x *= packednormal.w;
    7.  
    8.     fixed3 normal;
    9.     normal.xy = packednormal.xy * 2 - 1;
    10.     normal.z = sqrt(1 - saturate(dot(normal.xy, normal.xy)));
    11.     return normal;
    12. }
    When you take a RenderDoc capture, the normal maps appear red as well.

    Check if CopyTexture is doing the right thing in RenderDoc. Do not rely on the inspector. The inspector may show the 2D normal maps differently because it knows what they contain (after all you set the type when you import the texture). Also check if both source and destination have the texture format that you expect. Your screenshot says BC3 (=DXT5) but you mention BC7.
     
    Last edited: Aug 30, 2023
  3. suppertbw

    suppertbw

    Joined:
    Mar 16, 2016
    Posts:
    33
    The format is good and the difference here is the picture I captured is generated from a BC3 normal map, based on a trial of my attempt. And it seems sampling this Texture2DArray asset is correct. Maybe the inspector is wrong.