static public Texture2DArray Insert(Texture2DArray texArr, int pos, Texture2D tex)
        {
            bool linear = texArr.IsLinear();

            if (texArr == null || texArr.depth == 0)
            {
                texArr            = new Texture2DArray(tex.width, tex.height, 1, texArr.format, true, linear: linear);
                texArr.filterMode = FilterMode.Trilinear;
                texArr.SetTexture(tex, 0, apply: false);
                return(texArr);
            }

            if (pos > texArr.depth || pos < 0)
            {
                pos = texArr.depth;
            }

            Texture2DArray newArr = new Texture2DArray(texArr.width, texArr.height, texArr.depth + 1, texArr.format, true, linear: linear);

            newArr.name = texArr.name;

            if (pos != 0)
            {
                CopyTextures(texArr, newArr, pos);
            }
            if (pos != texArr.depth)
            {
                CopyTextures(texArr, pos, newArr, pos + 1, texArr.depth - pos);
            }

            if (tex != null)
            {
                newArr.SetTexture(tex, pos, apply: false);
            }

            newArr.Apply(updateMipmaps: false);
            return(newArr);
        }
        static public Texture2DArray WritableClone(this Texture2DArray texArr)
        {
            Texture2DArray newArr = new Texture2DArray(texArr.width, texArr.height, texArr.depth, texArr.format, true, linear: texArr.IsLinear());

            for (int i = 0; i < texArr.depth; i++)
            {
                CopyTexture(texArr, i, newArr, i);
            }

            newArr.Apply(updateMipmaps: true);
            return(newArr);
        }
        static public Texture2DArray FormattedClone(this Texture2DArray texArr, TextureFormat format)
        {
            Texture2DArray newArr = new Texture2DArray(texArr.width, texArr.height, texArr.depth, format, true, linear: texArr.IsLinear());

            newArr.name = texArr.name;

            int depth = texArr.depth;

            for (int i = 0; i < depth; i++)
            {
                CopyTexture(texArr, i, newArr, i);
            }

            newArr.Apply(updateMipmaps: false);
            return(newArr);
        }
        static public Texture2DArray ResizedClone(this Texture2DArray texArr, int newWidth, int newHeight)
        {
            Texture2DArray newArr = new Texture2DArray(newWidth, newHeight, texArr.depth, texArr.format, true, linear: texArr.IsLinear());

            newArr.name = texArr.name;

            for (int i = 0; i < texArr.depth; i++)
            {
                CopyTexture(texArr, i, newArr, i);
            }

            newArr.Apply(updateMipmaps: false);
            return(newArr);
        }
        static public Texture2DArray ChangeCount(Texture2DArray texArr, int newSize)
        {
            //if (texArr.depth == newSize) return texArr;

            Texture2DArray newArr = new Texture2DArray(texArr.width, texArr.height, newSize, texArr.format, true, linear: texArr.IsLinear());

            newArr.name = texArr.name;

            int min = newSize < texArr.depth? newSize : texArr.depth;

            CopyTextures(texArr, newArr, min);

            newArr.Apply(updateMipmaps: false);
            return(newArr);
        }
        static public Texture2DArray RemoveAt(Texture2DArray texArr, int num)
        {
            if (num >= texArr.depth || num < 0)
            {
                return(texArr);
            }

            Texture2DArray newArr = new Texture2DArray(texArr.width, texArr.height, texArr.depth - 1, texArr.format, true, linear: texArr.IsLinear());

            newArr.name = texArr.name;

            if (num != 0)
            {
                CopyTextures(texArr, newArr, num);
            }
            if (num != texArr.depth)
            {
                CopyTextures(texArr, num + 1, newArr, num, newArr.depth - num);
            }

            newArr.Apply(updateMipmaps: false);
            return(newArr);
        }
        static public void Clear(this Texture2DArray texArr, int chNum)
        /// Fills channel with blank without removing it
        {
            Texture2D temp = new Texture2D(texArr.width, texArr.height, texArr.format, true, linear: texArr.IsLinear());

            texArr.SetTexture(temp, chNum);
        }
        static public Texture2DArray InsertRange(Texture2DArray texArr, int pos, Texture2DArray addArr)
        {
            //if (texArr==null || texArr.depth==0) { return addArr; }
            if (pos > texArr.depth || pos < 0)
            {
                pos = texArr.depth;
            }

            Texture2DArray newArr = new Texture2DArray(texArr.width, texArr.height, texArr.depth + addArr.depth, texArr.format, true, linear: texArr.IsLinear());

            newArr.name = texArr.name;

            if (pos != 0)
            {
                CopyTextures(texArr, newArr, pos);
            }
            CopyTextures(addArr, 0, newArr, pos, addArr.depth);
            if (pos != texArr.depth)
            {
                CopyTextures(texArr, pos, newArr, pos + addArr.depth, texArr.depth - pos);
            }

            newArr.Apply(updateMipmaps: false);
            return(newArr);
        }
        public static Texture2DArray Add(Texture2DArray texArr, Texture2D tex)
        {
            Texture2DArray newArr = new Texture2DArray(texArr.width, texArr.height, texArr.depth + 1, texArr.format, true, linear: texArr.IsLinear());

            newArr.name = texArr.name;

            CopyTextures(texArr, newArr, texArr.depth);

            newArr.SetTexture(tex, texArr.depth, apply: false);

            newArr.Apply(updateMipmaps: false);
            return(newArr);
        }
        public static void CopyTextures(Texture2DArray srcArr, int srcIndex, Texture2DArray dstArr, int dstIndex, int length)
        /// Bulk textures copy from index to index
        {
            //format and size match
            if (srcArr.format == dstArr.format && srcArr.width == dstArr.width && srcArr.height == dstArr.height)
            {
                for (int i = 0; i < length; i++)
                {
                    Graphics.CopyTexture(srcArr, srcIndex + i, dstArr, dstIndex + i);
                }
                dstArr.Apply(updateMipmaps: false);
                return;
            }

            Texture2D tmpTex = new Texture2D(dstArr.width, dstArr.height, dstArr.format, true, linear: srcArr.IsLinear());

            for (int i = 0; i < length; i++)
            {
                srcArr.FillTexture(tmpTex, srcIndex + i);
                Graphics.CopyTexture(tmpTex, 0, dstArr, dstIndex + i);
            }

            dstArr.Apply(updateMipmaps: false);
        }
        public static Texture2D GetTexture(this Texture2DArray srcArr, int srcCh, bool readable = true)
        {
            Texture2D tex = new Texture2D(srcArr.width, srcArr.height, srcArr.format, true, linear: srcArr.IsLinear());

            Graphics.CopyTexture(srcArr, srcCh, tex, 0);
            tex.Apply(updateMipmaps: false, makeNoLongerReadable: !readable);
            return(tex);
        }
        public static Texture2D GetTexture(this Texture2DArray srcArr, int srcCh, bool readable = true)
        {
            Texture2D tex = null;

            try
            {
                tex = new Texture2D(srcArr.width, srcArr.height, srcArr.format, true, linear: srcArr.IsLinear());
                Graphics.CopyTexture(srcArr, srcCh, tex, 0);
                tex.Apply(updateMipmaps: false, makeNoLongerReadable: !readable);
            }
            catch (System.Exception e)
            {
                //Debug.LogError($"Could not load texture array texture: {e}");
                Debug.LogError("Could not load texture array texture: " + e);
            }
            return(tex);
        }