示例#1
0
        /// <summary>
        /// Third coord is num mipmaps.
        /// </summary>
        internal static void FindBestSizeAndMipCountAndFormatForTextureArrays(List <ShaderTextureProperty> texPropertyNames, int maxAtlasSize, MB_TextureArrayFormatSet targetFormatSet, MB_AtlasesAndRects[] resultAtlasesAndRectSlices,
                                                                              TexturePropertyData texturePropertyData)
        {
            texturePropertyData.sizes      = new Vector2[texPropertyNames.Count];
            texturePropertyData.doMips     = new bool[texPropertyNames.Count];
            texturePropertyData.numMipMaps = new int[texPropertyNames.Count];
            texturePropertyData.formats    = new TextureFormat[texPropertyNames.Count];
            for (int propIdx = 0; propIdx < texPropertyNames.Count; propIdx++)
            {
                int numSlices = resultAtlasesAndRectSlices.Length;
                texturePropertyData.sizes[propIdx] = new Vector3(16, 16, 1);
                bool hasMips  = false;
                int  mipCount = 1;
                for (int sliceIdx = 0; sliceIdx < numSlices; sliceIdx++)
                {
                    Debug.Assert(resultAtlasesAndRectSlices[sliceIdx].atlases.Length == texPropertyNames.Count);
                    Debug.Assert(resultAtlasesAndRectSlices[sliceIdx].texPropertyNames[propIdx] == texPropertyNames[propIdx].name);
                    Texture2D sliceTex = resultAtlasesAndRectSlices[sliceIdx].atlases[propIdx];
                    if (sliceTex != null)
                    {
                        if (sliceTex.mipmapCount > 1)
                        {
                            hasMips = true;
                        }
                        mipCount = Mathf.Max(mipCount, sliceTex.mipmapCount);
                        texturePropertyData.sizes[propIdx].x = Mathf.Min(Mathf.Max(texturePropertyData.sizes[propIdx].x, sliceTex.width), maxAtlasSize);
                        texturePropertyData.sizes[propIdx].y = Mathf.Min(Mathf.Max(texturePropertyData.sizes[propIdx].y, sliceTex.height), maxAtlasSize);
                        //texturePropertyData.sizes[propIdx].z = Mathf.Max(texturePropertyData.sizes[propIdx].z, sliceTex.mipmapCount);
                        texturePropertyData.formats[propIdx] = targetFormatSet.GetFormatForProperty(texPropertyNames[propIdx].name);
                    }
                }

                int numberMipsForMaxAtlasSize = Mathf.CeilToInt(Mathf.Log(maxAtlasSize, 2)) + 1;
                texturePropertyData.numMipMaps[propIdx] = Mathf.Min(numberMipsForMaxAtlasSize, mipCount);
                texturePropertyData.doMips[propIdx]     = hasMips;
            }
        }
示例#2
0
        /// <summary>
        /// Creates one texture array per texture property.
        /// </summary>
        /// <returns></returns>
        internal static Texture2DArray[] CreateTextureArraysForResultMaterial(TexturePropertyData texPropertyData, List <ShaderTextureProperty> masterListOfTexProperties, MB_AtlasesAndRects[] resultAtlasesAndRectSlices,
                                                                              bool[] hasTexForProperty, MB3_TextureCombiner combiner, MB2_LogLevel LOG_LEVEL)
        {
            Debug.Assert(texPropertyData.sizes.Length == hasTexForProperty.Length);

            // ASSUMPTION all slices in the same format and the same size, alpha channel and mipMapCount
            string[] texPropertyNames = resultAtlasesAndRectSlices[0].texPropertyNames;
            Debug.Assert(texPropertyNames.Length == hasTexForProperty.Length);
            Texture2DArray[] texArrays = new Texture2DArray[texPropertyNames.Length];

            // Each texture property (_MainTex, _Bump, ...) becomes a Texture2DArray
            for (int propIdx = 0; propIdx < texPropertyNames.Length; propIdx++)
            {
                if (!hasTexForProperty[propIdx])
                {
                    continue;
                }
                string        propName  = texPropertyNames[propIdx];
                int           numSlices = resultAtlasesAndRectSlices.Length;
                int           w         = (int)texPropertyData.sizes[propIdx].x;
                int           h         = (int)texPropertyData.sizes[propIdx].y;
                int           numMips   = (int)texPropertyData.numMipMaps[propIdx];
                TextureFormat format    = texPropertyData.formats[propIdx];
                bool          doMipMaps = texPropertyData.doMips[propIdx];

                Debug.Assert(QualitySettings.desiredColorSpace == QualitySettings.activeColorSpace, "Wanted to use color space " + QualitySettings.desiredColorSpace + " but the activeColorSpace was " + QualitySettings.activeColorSpace + " hardware may not support the desired color space.");

                bool isLinear = MBVersion.GetProjectColorSpace() == ColorSpace.Linear;
                {
                    if (IsLinearProperty(masterListOfTexProperties, propName))
                    {
                        isLinear = true;
                    }
                    else
                    {
                        isLinear = false;
                    }
                }

                Texture2DArray texArray = new Texture2DArray(w, h, numSlices, format, doMipMaps, isLinear);
                if (LOG_LEVEL >= MB2_LogLevel.info)
                {
                    Debug.LogFormat("Creating Texture2DArray for property: {0} w: {1} h: {2} format: {3} doMips: {4} isLinear: {5}", propName, w, h, format, doMipMaps, isLinear);
                }
                for (int sliceIdx = 0; sliceIdx < numSlices; sliceIdx++)
                {
                    Debug.Assert(resultAtlasesAndRectSlices[sliceIdx].atlases.Length == texPropertyNames.Length);
                    Debug.Assert(resultAtlasesAndRectSlices[sliceIdx].texPropertyNames[propIdx] == propName);
                    Texture2D srcTex = resultAtlasesAndRectSlices[sliceIdx].atlases[propIdx];

                    if (LOG_LEVEL >= MB2_LogLevel.debug)
                    {
                        Debug.LogFormat("Slice: {0}  texture: {1}", sliceIdx, srcTex);
                    }
                    bool isCopy = false;
                    if (srcTex == null)
                    {
                        if (LOG_LEVEL >= MB2_LogLevel.trace)
                        {
                            Debug.LogFormat("Texture is null for slice: {0} creating temporary texture", sliceIdx);
                        }
                        // Slices might not have all textures create a dummy if needed.
                        srcTex = combiner._createTemporaryTexture(propName, w, h, format, doMipMaps, isLinear);
                    }

                    Debug.Assert(srcTex.width == texArray.width, "Source texture is not the same width as the texture array '" + srcTex + " srcWidth:" + srcTex.width + " texArrayWidth:" + texArray.width);
                    Debug.Assert(srcTex.height == texArray.height, "Source texture is not the same height as the texture array " + srcTex + " srcWidth:" + srcTex.height + " texArrayWidth:" + texArray.height);
                    Debug.Assert(srcTex.mipmapCount == numMips, "Source texture does have not the same number of mips as the texture array: " + srcTex + " numMipsTex: " + srcTex.mipmapCount + " numMipsTexArray: " + numMips + " texDims: " + srcTex.width + "x" + srcTex.height);
                    Debug.Assert(srcTex.format == format, "Formats should have been converted before this. Texture: " + srcTex + "Source: " + srcTex.format + " Targ: " + format);

                    for (int mipIdx = 0; mipIdx < numMips; mipIdx++)
                    {
                        Graphics.CopyTexture(srcTex, 0, mipIdx, texArray, sliceIdx, mipIdx);
                    }

                    if (isCopy)
                    {
                        MB_Utility.Destroy(srcTex);
                    }
                }

                texArray.Apply();
                texArrays[propIdx] = texArray;
            }

            return(texArrays);
        }
示例#3
0
        internal static bool ConvertTexturesToReadableFormat(TexturePropertyData texturePropertyData,
                                                             MB_AtlasesAndRects[] resultAtlasesAndRectSlices,
                                                             bool[] hasTexForProperty, List <ShaderTextureProperty> textureShaderProperties,
                                                             MB3_TextureCombiner combiner,
                                                             MB2_LogLevel logLevel,
                                                             List <Texture2D> createdTemporaryTextureAssets,
                                                             MB2_EditorMethodsInterface textureEditorMethods)
        {
            for (int propIdx = 0; propIdx < hasTexForProperty.Length; propIdx++)
            {
                if (!hasTexForProperty[propIdx])
                {
                    continue;
                }

                TextureFormat format = texturePropertyData.formats[propIdx];

                if (!textureEditorMethods.TextureImporterFormatExistsForTextureFormat(format))
                {
                    Debug.LogError("Could not find target importer format matching " + format);
                    return(false);
                }

                int numSlices    = resultAtlasesAndRectSlices.Length;
                int targetWidth  = (int)texturePropertyData.sizes[propIdx].x;
                int targetHeight = (int)texturePropertyData.sizes[propIdx].y;
                for (int sliceIdx = 0; sliceIdx < numSlices; sliceIdx++)
                {
                    Texture2D sliceTex = resultAtlasesAndRectSlices[sliceIdx].atlases[propIdx];

                    Debug.Assert(sliceTex != null, "sliceIdx " + sliceIdx + " " + propIdx);
                    if (sliceTex != null)
                    {
                        if (!MBVersion.IsTextureReadable(sliceTex))
                        {
                            textureEditorMethods.SetReadWriteFlag(sliceTex, true, true);
                        }

                        bool isAsset = textureEditorMethods.IsAnAsset(sliceTex);
                        if (logLevel >= MB2_LogLevel.trace)
                        {
                            Debug.Log("Considering format of texture: " + sliceTex + " format:" + sliceTex.format);
                        }
                        if ((sliceTex.width != targetWidth || sliceTex.height != targetHeight) ||
                            (!isAsset && sliceTex.format != format))
                        {
                            // Do this the horrible hard way. It is only possible to resize textures in TrueColor formats,
                            // And only possible to switch formats using the Texture importer.
                            // Create a resized temporary texture asset in ARGB32 format. Then set its texture format and reimport
                            resultAtlasesAndRectSlices[sliceIdx].atlases[propIdx] = textureEditorMethods.CreateTemporaryAssetCopy(textureShaderProperties[propIdx], sliceTex, targetWidth, targetHeight, format, logLevel);
                            createdTemporaryTextureAssets.Add(resultAtlasesAndRectSlices[sliceIdx].atlases[propIdx]);
                        }
                        else if (sliceTex.format != format)
                        {
                            textureEditorMethods.ConvertTextureFormat_PlatformOverride(sliceTex, format, textureShaderProperties[propIdx].isNormalMap);
                        }
                    }
                    else
                    {
                    }

                    if (resultAtlasesAndRectSlices[sliceIdx].atlases[propIdx].format != format)
                    {
                        Debug.LogError("Could not convert texture to format " + format +
                                       ". This can happen if the target build platform in build settings does not support textures in this format." +
                                       " It may be necessary to switch the build platform in order to build texture arrays in this format.");
                        return(false);
                    }
                }
            }

            return(true);
        }
        /// <summary>
        /// Creates one texture array per texture property.
        /// </summary>
        /// <returns></returns>
        internal static Texture2DArray[] CreateTextureArraysForResultMaterial(TexturePropertyData texPropertyData, MB_AtlasesAndRects[] resultAtlasesAndRectSlices,
                                                                              bool[] hasTexForProperty, MB3_TextureCombiner combiner, MB2_LogLevel LOG_LEVEL)
        {
            Debug.Assert(texPropertyData.sizes.Length == hasTexForProperty.Length);

            // ASSUMPTION all slices in the same format and the same size, alpha channel and mipMapCount
            string[] texPropertyNames = resultAtlasesAndRectSlices[0].texPropertyNames;
            Debug.Assert(texPropertyNames.Length == hasTexForProperty.Length);
            Texture2DArray[] texArrays = new Texture2DArray[texPropertyNames.Length];

            // Each texture property (_MainTex, _Bump, ...) becomes a Texture2DArray
            for (int propIdx = 0; propIdx < texPropertyNames.Length; propIdx++)
            {
                if (!hasTexForProperty[propIdx])
                {
                    continue;
                }

                int            numSlices = resultAtlasesAndRectSlices.Length;
                int            w         = (int)texPropertyData.sizes[propIdx].x;
                int            h         = (int)texPropertyData.sizes[propIdx].y;
                int            numMips   = (int)texPropertyData.numMipMaps[propIdx];
                TextureFormat  format    = texPropertyData.formats[propIdx];
                bool           doMipMaps = texPropertyData.doMips[propIdx];
                Texture2DArray texArray  = new Texture2DArray(w, h, numSlices, format, doMipMaps);
                if (LOG_LEVEL >= MB2_LogLevel.info)
                {
                    Debug.LogFormat("Creating Texture2DArray for property: {0} w: {1} h: {2} format: {3} doMips: {4}", texPropertyNames[propIdx], w, h, format, doMipMaps);
                }
                for (int sliceIdx = 0; sliceIdx < numSlices; sliceIdx++)
                {
                    Debug.Assert(resultAtlasesAndRectSlices[sliceIdx].atlases.Length == texPropertyNames.Length);
                    Debug.Assert(resultAtlasesAndRectSlices[sliceIdx].texPropertyNames[propIdx] == texPropertyNames[propIdx]);
                    Texture2D srcTex = resultAtlasesAndRectSlices[sliceIdx].atlases[propIdx];

                    if (LOG_LEVEL >= MB2_LogLevel.debug)
                    {
                        Debug.LogFormat("Slice: {0}  texture: {1}", sliceIdx, srcTex);
                    }
                    bool isCopy = false;
                    if (srcTex == null)
                    {
                        // Slices might not have all textures create a dummy if needed.
                        srcTex = combiner._createTemporaryTexture(texPropertyNames[propIdx], w, h, format, doMipMaps);
                    }

                    Debug.Assert(srcTex.width == texArray.width, "Source texture is not the same width as the texture array " + srcTex);
                    Debug.Assert(srcTex.height == texArray.height, "Source texture is not the same height as the texture array " + srcTex);
                    Debug.Assert(srcTex.mipmapCount == numMips, "Source texture does have not the same number of mips as the texture array: " + srcTex + " numMipsTex: " + srcTex.mipmapCount + " numMipsTexArray: " + numMips + " texDims: " + srcTex.width + "x" + srcTex.height);
                    Debug.Assert(srcTex.format == format, "Formats should have been converted before this. Texture: " + srcTex + "Source: " + srcTex.format + " Targ: " + format);

                    for (int mipIdx = 0; mipIdx < numMips; mipIdx++)
                    {
                        Graphics.CopyTexture(srcTex, 0, mipIdx, texArray, sliceIdx, mipIdx);
                    }

                    if (isCopy)
                    {
                        MB_Utility.Destroy(srcTex);
                    }
                }

                texArray.Apply();
                texArrays[propIdx] = texArray;
            }

            return(texArrays);
        }