Exemplo n.º 1
0
        /// <summary>
        /// Setup data for atlas building.
        /// </summary>
        /// <param name="_umaData">UMA data.</param>
        /// <param name="_umaGenerator">UMA generator.</param>
        public void ProcessTexture(UMAData _umaData, UMAGeneratorBase _umaGenerator)
        {
            umaData = _umaData;
            umaGenerator = _umaGenerator;
            if (umaGenerator is UMAGenerator)
            {
                fastPath = (umaGenerator as UMAGenerator).fastGeneration;
            }

            if (umaData.atlasResolutionScale <= 0) umaData.atlasResolutionScale = 1f;
            var textureMerge = umaGenerator.textureMerge;
            textureMerge.RefreshMaterials();
            if (textureMerge == null)
            {
                if (Debug.isDebugBuild)
                    Debug.LogError("TextureMerge is null!");
                // yield return null;
            }
            try
            {
                for (int atlasIndex = umaData.generatedMaterials.materials.Count - 1; atlasIndex >= 0; atlasIndex--)
                {
                    var generatedMaterial = umaData.generatedMaterials.materials[atlasIndex];

                    //Rendering Atlas
                    int moduleCount = 0;

                    //Process all necessary TextureModules
                    for (int i = 0; i < generatedMaterial.materialFragments.Count; i++)
                    {
                        if (!generatedMaterial.materialFragments[i].isRectShared && !generatedMaterial.materialFragments[i].isNoTextures)
                        {
                            moduleCount++;
                            moduleCount = moduleCount + generatedMaterial.materialFragments[i].overlays.Length;
                        }
                    }
                    textureMerge.EnsureCapacity(moduleCount);

                    var slotData = generatedMaterial.materialFragments[0].slotData;
                    resultingTextures = new Texture[slotData.material.channels.Length];
                    for (int textureType = slotData.material.channels.Length - 1; textureType >= 0; textureType--)
                    {
                        switch (slotData.material.channels[textureType].channelType)
                        {
                            case UMAMaterial.ChannelType.Texture:
                            case UMAMaterial.ChannelType.DiffuseTexture:
                            case UMAMaterial.ChannelType.NormalMap:
                            case UMAMaterial.ChannelType.DetailNormalMap:
                                {
                                    bool CopyRTtoTex = SupportsRTToTexture2D && fastPath;

                                    textureMerge.Reset();
                                    for (int i = 0; i < generatedMaterial.materialFragments.Count; i++)
                                    {
                                        textureMerge.SetupModule(generatedMaterial, i, textureType);
                                    }

                                    //last element for this textureType
                                    moduleCount = 0;

                                    int width = Mathf.FloorToInt(generatedMaterial.cropResolution.x);
                                    int height = Mathf.FloorToInt(generatedMaterial.cropResolution.y);

                                    if (width == 0 || height == 0)
                                    {
                                        continue;
                                    }

                                    //this should be restricted to >= 1 but 0 was allowed before and projects may have the umaMaterial value serialized to 0.
                                    float downSample = (slotData.material.channels[textureType].DownSample == 0) ? 1f : (1f / slotData.material.channels[textureType].DownSample);

                                    destinationTexture = new RenderTexture(Mathf.FloorToInt(generatedMaterial.cropResolution.x * umaData.atlasResolutionScale * downSample), Mathf.FloorToInt(generatedMaterial.cropResolution.y * umaData.atlasResolutionScale * downSample), 0, slotData.material.channels[textureType].textureFormat, RenderTextureReadWrite.Linear);
                                    destinationTexture.filterMode = FilterMode.Point;
                                    destinationTexture.useMipMap = umaGenerator.convertMipMaps && CopyRTtoTex;// && !umaGenerator.convertRenderTexture;
                                    destinationTexture.name = slotData.material.name + " Chan " + textureType + " frame: " + Time.frameCount;

                                    //Draw all the Rects here

                                    Color backgroundColor;
                                    UMAMaterial.ChannelType channelType = slotData.material.channels[textureType].channelType;

                                    if (slotData.material.MaskWithCurrentColor && (channelType == UMAMaterial.ChannelType.DiffuseTexture || channelType == UMAMaterial.ChannelType.Texture || channelType == UMAMaterial.ChannelType.TintedTexture))
                                    {
                                        backgroundColor = slotData.material.maskMultiplier * textureMerge.camBackgroundColor;
                                    }
                                    else
                                    {
                                        backgroundColor = UMAMaterial.GetBackgroundColor(slotData.material.channels[textureType].channelType);
                                    }

                                    textureMerge.DrawAllRects(destinationTexture, width, height, backgroundColor, umaGenerator.SharperFitTextures);

                                    //PostProcess
                                    textureMerge.PostProcess(destinationTexture, slotData.material.channels[textureType].channelType);

                                    if (umaGenerator.convertRenderTexture || slotData.material.channels[textureType].ConvertRenderTexture)
                                    {
                                        #region Convert Render Textures
									if(CopyRTtoTex) {
                                            // copy the texture with mips to the Texture2D
                                            Texture2D tempTexture;
                                            tempTexture = new Texture2D(destinationTexture.width, destinationTexture.height, TextureFormat.ARGB32, umaGenerator.convertMipMaps, true);
                                            Graphics.CopyTexture(destinationTexture, tempTexture);
                                            destinationTexture.Release();
                                            UnityEngine.GameObject.DestroyImmediate(destinationTexture);

                                            tempTexture.wrapMode = TextureWrapMode.Repeat;
                                            tempTexture.anisoLevel = slotData.material.AnisoLevel;
                                            tempTexture.mipMapBias = slotData.material.MipMapBias;
                                            tempTexture.filterMode = slotData.material.MatFilterMode;
                                            resultingTextures[textureType] = tempTexture as Texture;

										if(!slotData.material.channels[textureType].NonShaderTexture) {
                                                if (generatedMaterial.umaMaterial.translateSRP)
                                                {
                                                    generatedMaterial.material.SetTexture(UMAUtils.TranslatedSRPTextureName(slotData.material.channels[textureType].materialPropertyName), tempTexture);
                                                }
                                                else
                                                {
                                                    generatedMaterial.material.SetTexture(slotData.material.channels[textureType].materialPropertyName, tempTexture);
                                                }
                                            }
									} else {
#if USE_ASYNC_GPU_READBACK
                                            // Todo: use AsyncGPUReadback to get the texture if possible.
                                            //       
                                            // material == generatedMaterial.material
                                            // umaData ==  ;
                                            // slotData == ;
                                            // propname == slotData.material.channels[textureType].materialPropertyName
                                            // mipcount
                                            // mipsconverted[]
                                            // Data.
                                            //for (int i=0;i< destinationTexture.mipmapCount;i++)
                                            //{
                                            // 
                                            //}
#else
                                            Texture2D tempTexture;

                                            tempTexture = new Texture2D(destinationTexture.width, destinationTexture.height, TextureFormat.ARGB32, umaGenerator.convertMipMaps, true);

                                            RenderTexture.active = destinationTexture;
                                            tempTexture.ReadPixels(new Rect(0, 0, destinationTexture.width, destinationTexture.height), 0, 0, umaGenerator.convertMipMaps);

                                            //resultingTextures[textureType] = tempTexture as Texture;
                                            RenderTexture.active = null;
                                            destinationTexture.Release();
                                            UnityEngine.GameObject.DestroyImmediate(destinationTexture);
                                            // if (!fastPath) yield return 6;
                                            //tempTexture = resultingTextures[textureType] as Texture2D;
                                            tempTexture.Apply();
                                            tempTexture.wrapMode = TextureWrapMode.Repeat;
                                            tempTexture.anisoLevel = slotData.material.AnisoLevel;
                                            tempTexture.mipMapBias = slotData.material.MipMapBias;
                                            tempTexture.filterMode = slotData.material.MatFilterMode;
                                            //if (slotData.asset.material.channels[textureType].Compression != UMAMaterial.CompressionSettings.None)
                                            //{
                                            //    tempTexture.Compress(slotData.asset.material.channels[textureType].Compression == UMAMaterial.CompressionSettings.HighQuality);
                                            // }
                                            resultingTextures[textureType] = tempTexture;
										if(!slotData.material.channels[textureType].NonShaderTexture) {
                                                if (generatedMaterial.umaMaterial.translateSRP)
                                                {
                                                    generatedMaterial.material.SetTexture(UMAUtils.TranslatedSRPTextureName(slotData.material.channels[textureType].materialPropertyName), tempTexture);
                                                }
                                                else
                                                {
                                                    generatedMaterial.material.SetTexture(slotData.material.channels[textureType].materialPropertyName, tempTexture);
                                                }

    											generatedMaterial.material.SetTexture(UMAUtils.TranslatedSRPTextureName(slotData.material.channels[textureType].materialPropertyName), tempTexture);

                                            }
                                        }
#endif
                                        #endregion
                                    }
                                    else
                                    {
                                        destinationTexture.anisoLevel = slotData.material.AnisoLevel;
                                        destinationTexture.mipMapBias = slotData.material.MipMapBias;
                                        destinationTexture.filterMode = slotData.material.MatFilterMode;
                                        destinationTexture.wrapMode = TextureWrapMode.Repeat;
                                        resultingTextures[textureType] = destinationTexture;
                                        if (!slotData.material.channels[textureType].NonShaderTexture)
                                        {
                                            if (generatedMaterial.umaMaterial.translateSRP)
                                            {
                                                generatedMaterial.material.SetTexture(UMAUtils.TranslatedSRPTextureName(slotData.material.channels[textureType].materialPropertyName), destinationTexture);
                                            }
                                            else
                                            {
                                                generatedMaterial.material.SetTexture(slotData.material.channels[textureType].materialPropertyName, destinationTexture);
                                            }
                                        }
                                    }

                                    break;
                                }
                            case UMAMaterial.ChannelType.MaterialColor:
                                {
                                    if (slotData.material.channels[textureType].NonShaderTexture) break;
                                    generatedMaterial.material.SetColor(slotData.material.channels[textureType].materialPropertyName, generatedMaterial.materialFragments[0].baseColor);
                                    break;
                                }
                            case UMAMaterial.ChannelType.TintedTexture:
                                {
                                    for (int i = 0; i < generatedMaterial.materialFragments.Count; i++)
                                    {
                                        var fragment = generatedMaterial.materialFragments[i];
                                        if (fragment.isRectShared) continue;
                                        for (int j = 0; j < fragment.baseOverlay.textureList.Length; j++)
                                        {
                                            if (fragment.baseOverlay.textureList[j] != null)
                                            {
                                                if (!slotData.material.channels[textureType].NonShaderTexture)
                                                {
                                                    if (generatedMaterial.umaMaterial.translateSRP)
                                                    {
                                                        generatedMaterial.material.SetTexture(UMAUtils.TranslatedSRPTextureName(slotData.material.channels[j].materialPropertyName), fragment.baseOverlay.textureList[j]);
                                                    }
                                                    else
                                                    {
                                                        generatedMaterial.material.SetTexture(slotData.material.channels[j].materialPropertyName, fragment.baseOverlay.textureList[j]);
                                                    }
                                                }
                                                if (j == 0)
                                                {
                                                    generatedMaterial.material.color = fragment.baseColor;
                                                }
                                            }
                                        }
                                        foreach (var overlay in fragment.overlays)
                                        {
                                            if (generatedMaterial.textureNameList == null)
                                                for (int j = 0; j < overlay.textureList.Length; j++)
                                                {
                                                    if (overlay.textureList[j] != null)
                                                    {
                                                        if (!slotData.material.channels[textureType].NonShaderTexture)
                                                        {
                                                            if (generatedMaterial.umaMaterial.translateSRP)
                                                            {
                                                                generatedMaterial.material.SetTexture(UMAUtils.TranslatedSRPTextureName(slotData.material.channels[j].materialPropertyName), overlay.textureList[j]);
                                                            }
                                                            else
                                                            {
                                                                generatedMaterial.material.SetTexture(slotData.material.channels[j].materialPropertyName, overlay.textureList[j]);
                                                            }
                                                        }
                                                    }
                                                }
                                        }
                                    }
                                    break;
                                }
                        }
                    }
                    generatedMaterial.resultingAtlasList = resultingTextures;
                }
            }
            finally
            {
                RenderTexture.active = null;
            }
        }