Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Texture2DArray Can not create compressed format. Small Editor Demo

Discussion in 'Shaders' started by Quatum1000, Mar 8, 2017.

  1. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    Hi everyone,

    I stuck currently to create Texture2Darray with a compresses format.
    The reason is

    Texture2DArray array = new Texture2DArray(textures[0].width, textures[0].height, textures.Length, textures[0].format, true);

    Array. provide only SetPixels and SetPixels32 and these both requires RGB and RGBA format only. But not BC7/DXT5 or the newer compression typ.

    Does any know how to build a compressed Texture2DArray and provide some lines of code please?!

    Thanks a lot!
    __________________________________________________________________


    With this small example you're able to select a brunch of textures and save them as Texture2DArray asset to the same directory in Unity. Drag and drop the file was created to the Tex2DArray shader slot myArr.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.IO;
    4.  
    5. public class EditorExportAsset {
    6.     [MenuItem("Assets/Build : Texture2DArray Asset From Selection")]
    7.     static void ExportResource() {
    8.  
    9.         // Selection is unsorted and does not reflect the sort of the displayed filenames of unity
    10.         Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
    11.  
    12.         if (selection.Length > 0) {
    13.  
    14.             // Redirect to the Path of the first selected object
    15.             string pathfull = new FileInfo(AssetDatabase.GetAssetPath(selection[0])).FullName;
    16.             // FileInfo reversed IBM format back to Unity
    17.             pathfull = pathfull.Replace("\\", "/");
    18.  
    19.             string name = selection[0].name.ToLower();
    20.             var pathfull_l = pathfull.ToLower();
    21.             pathfull = pathfull.Substring(0, pathfull_l.LastIndexOf("/"+name));
    22.  
    23.             // Debug.Log(pathfull +  "   " + pathfull_l.LastIndexOf("/" + name)  +  "  " +name) ;
    24.  
    25.             // Bring up save panel
    26.             pathfull = EditorUtility.SaveFilePanel("Save Resource Texture2DArray", pathfull, "Texture2DArray", "asset");
    27.  
    28.             // Create relative Path for AssetDatabase.Save
    29.             pathfull_l = pathfull.ToLower();
    30.             pathfull = pathfull.Substring(pathfull_l.IndexOf("/assets/") + 1);
    31.                      
    32.             if (pathfull.Length != 0) {
    33.  
    34.                 // Build the resource file from the active selection.
    35.                 Texture2D[] textures = new Texture2D[selection.Length];
    36.  
    37.                 //Debug.Log(textures[0].format);
    38.  
    39.                 for (int i = 0; i < textures.Length; i++) {
    40.                     textures[i] = (Texture2D)selection[i];
    41.                 }
    42.  
    43.                 Texture2DArray array = new Texture2DArray(textures[0].width, textures[0].height, textures.Length, textures[0].format, true);
    44.  
    45.                 // Graphics.CopyTexture() ??
    46.                 for (int i = 0; i < textures.Length; i++)
    47.                     array.SetPixels32(textures[i].GetPixels32(), i);
    48.  
    49.                 array.Apply();
    50.  
    51.                 AssetDatabase.CreateAsset(array, pathfull);
    52.             }
    53.  
    54.         } else {
    55.             Debug.LogWarning("# Build Texture2DArray Asset From Selection : No Selection ");
    56.         }
    57.     }
    58. }

    Code (CSharp):
    1. Shader "Example/TextureArrayShader" {
    2.     Properties{
    3.         _Color("Color", Color) = (1,1,1,1)
    4.         _MyArr("Tex", 2DArray) = "" {}
    5.         _Index("Texture Index", Int) = 0
    6.         _Glossiness("Smoothness", Range(0,1)) = 0.5
    7.         _Metallic("Metallic", Range(0,1)) = 0.0
    8.     }
    9.         SubShader{
    10.         Tags{ "RenderType" = "Opapue" }
    11.         LOD 200
    12.  
    13.         CGPROGRAM
    14.         // Physically based Standard lighting model, and enable shadows on all light types
    15. #pragma surface surf Standard fullforwardshadows
    16.  
    17.         // Use shader model 3.5 target, to get
    18. #pragma target 3.5
    19.  
    20.         UNITY_DECLARE_TEX2DARRAY(_MyArr);
    21.  
    22.     struct Input {
    23.         float2 uv_MyArr;
    24.     };
    25.  
    26.     half _Glossiness;
    27.     half _Metallic;
    28.     fixed4 _Color;
    29.  
    30.     float _Index;
    31.  
    32.     void surf(Input IN, inout SurfaceOutputStandard o) {
    33.         // Albedo comes from a texture tinted by color
    34.         // 2nd attribute is float3 !!! uvs and index
    35.         fixed4 c = UNITY_SAMPLE_TEX2DARRAY(_MyArr, float3(IN.uv_MyArr, _Index)) * _Color;
    36.         o.Albedo = c.rgb;
    37.         // Metallic and smoothness come from slider variables
    38.         o.Metallic = _Metallic;
    39.         o.Smoothness = _Glossiness;
    40.         o.Alpha = c.a;
    41.     }
    42.     ENDCG
    43.     }
    44.         FallBack "Diffuse"
    45. }
    46.  
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
  3. sewy

    sewy

    Joined:
    Oct 11, 2015
    Posts:
    150
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Not enough information there to give an answer, and I don't post on Unity Answers. Please make a new thread here.
     
  5. sewy

    sewy

    Joined:
    Oct 11, 2015
    Posts:
    150
    I am using Graphics.CopyTexture for the copying into Texture2DArray using:
    Code (CSharp):
    1. // Create Texture2DArray using one of the textures
    2. Texture2DArray texture2DArray = new Texture2DArray(texture.width, texture.height, length, texture.format, true, false);
    3. texture2DArray.filterMode = texture.filterMode;
    4. texture2DArray.wrapMode = texture.wrapMode;
    5.  
    6. //Copy to texture2DArray
    7. for(int i = 0; i < texture.mipmapCount; i++) { // Copy all mipmap levels
    8.       Graphics.CopyTexture(texture, 0, i, texture2DArray, indexIntoTexture2DArray, i); texture2DArray
    9. }
    With uncompressed textures, everything works fine, but when used with compressed DXT1(BC7) textures, I am getting:

    Invalid texture format: 10(25)
    UnityEngine.Graphics:CopyTexture(Texture, Int32, Int32, Texture, Int32, Int32)
    Image invalid format!
    UnityEngine.Graphics:CopyTexture(Texture, Int32, Int32, Texture, Int32, Int32)

    I am using Unity 2018.3 with Forward only (prepared for VR). If you will need more info, please dont hesitate.
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    That's telling me that you're trying to copy a DXT1 format texture into a BC7 format texture array. Those are not the same format.
     
  7. sewy

    sewy

    Joined:
    Oct 11, 2015
    Posts:
    150
    Nope, just saying it's happening in both compressions.
    Imagine having a texture, I will create a texture2Darray able to hold this texture (same dimensions, type, wrap mode, etc.) using the code above and then copy it and all of its mip maps into texture2Darray.
     
  8. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    This works for me without errors, in the editor at least.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. #if UNITY_EDITOR
    5. using UnityEditor;
    6. #endif
    7.  
    8. public class TextureArrayTest : MonoBehaviour {
    9.     public Texture2D[] textures;
    10.     public Texture2DArray tempTextureArray;
    11.  
    12.     public void Go()
    13.     {
    14.         Texture2DArray texture2DArray = new Texture2DArray(textures[0].width, textures[0].height, textures.Length, textures[0].format, true, false);
    15.         for(int i = 0; i < textures.Length; i++)
    16.         {
    17.             for(int m = 0; m < textures[i].mipmapCount; m++)
    18.             {
    19.                 Graphics.CopyTexture(textures[i], 0, m, texture2DArray, i, m);
    20.             }
    21.         }
    22.         if (tempTextureArray != null)
    23.             DestroyImmediate(tempTextureArray);
    24.         tempTextureArray = texture2DArray;
    25.     }
    26. }
    27.  
    28. #if UNITY_EDITOR
    29. [CustomEditor(typeof(TextureArrayTest))]
    30. public class TextureArrayTestEditor : Editor
    31. {
    32.     public override void OnInspectorGUI()
    33.     {
    34.         base.OnInspectorGUI();
    35.  
    36.         if (GUILayout.Button("Make Array"))
    37.             (target as TextureArrayTest).Go();
    38.     }
    39. }
    40. #endif
    That leads me to believe you're getting the error on a platform that doesn't support CopyTexture?
     
    Last edited: Nov 13, 2018
  9. sewy

    sewy

    Joined:
    Oct 11, 2015
    Posts:
    150
    With compressed textures Im still getting similar error, although the texture2DArray is filled (as in my scrips).

    About the platform,
     Debug.Log(SystemInfo.copyTextureSupport)

    returns
    Basic, Copy3D, DifferentTypes, TextureToRT, RTToTexture

    And having NVIDIA GTX 1080 Ti so that should not be problem.

    Here is the image of texture setting.
     

    Attached Files:

  10. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    If your using the latest 2018.3 betas, Unity broke CopyTexture with texture arrays.
     
    R0man, VictorKs, sewy and 1 other person like this.
  11. sewy

    sewy

    Joined:
    Oct 11, 2015
    Posts:
    150
    Lal.. confirmed. Tried in 2018.2.8f1 and no problem. In 2018.3.0b7 error occured, but textures are copied in Tex2DArray.

    Thanks both of you!