public Color GetColorForTemporaryTexture(Material matIfBlender, ShaderTextureProperty texProperty)
            {
                Debug.Assert(_textureProperties._considerNonTextureProperties == false);
                if (texProperty.isNormalMap)
                {
                    return(NEUTRAL_NORMAL_MAP_COLOR);
                }

                else if (_textureProperties.textureProperty2DefaultColorMap.ContainsKey(texProperty.name))
                {
                    return(_textureProperties.textureProperty2DefaultColorMap[texProperty.name]);
                }

                return(new Color(1f, 1f, 1f, 0f));
            }
        public override bool Equals(object obj)
        {
            if (!(obj is ShaderTextureProperty))
            {
                return(false);
            }
            ShaderTextureProperty b = (ShaderTextureProperty)obj;

            if (!name.Equals(b.name))
            {
                return(false);
            }
            if (isNormalMap != b.isNormalMap)
            {
                return(false);
            }
            return(true);
        }
示例#3
0
 public Color GetColorIfNoTexture(Material mat, ShaderTextureProperty texProperty)
 {
     if (texProperty.isNormalMap)
     {
         return(new Color(.5f, .5f, 1f));
     }
     else if (texProperty.name.Equals("_MainTex"))
     {
         if (mat != null && mat.HasProperty("_Color"))
         {
             try
             { //need try because can't garantee _Color is a color
                 return(mat.GetColor("_Color"));
             }
             catch (Exception) { }
         }
         else if (mat != null && mat.HasProperty("_TintColor"))
         {
             try
             {                     //need try because can't garantee _TintColor is a color
                 return(mat.GetColor("_TintColor"));
             }
             catch (Exception) { }
         }
     }
     else if (texProperty.name.Equals("_SpecGlossMap"))
     {
         if (mat != null && mat.HasProperty("_SpecColor"))
         {
             try
             { //need try because can't garantee _Color is a color
                 Color c = mat.GetColor("_SpecColor");
                 if (mat.HasProperty("_Glossiness"))
                 {
                     try
                     {
                         c.a = mat.GetFloat("_Glossiness");
                     }
                     catch (Exception) { }
                 }
                 Debug.LogWarning(c);
                 return(c);
             }
             catch (Exception) { }
         }
     }
     else if (texProperty.name.Equals("_MetallicGlossMap"))
     {
         if (mat != null && mat.HasProperty("_Metallic"))
         {
             try
             { //need try because can't garantee _Metallic is a float
                 float v = mat.GetFloat("_Metallic");
                 Color c = new Color(v, v, v);
                 if (mat.HasProperty("_Glossiness"))
                 {
                     try
                     {
                         c.a = mat.GetFloat("_Glossiness");
                     }
                     catch (Exception) { }
                 }
                 return(c);
             }
             catch (Exception) { }
         }
     }
     else if (texProperty.name.Equals("_ParallaxMap"))
     {
         return(new Color(0f, 0f, 0f, 0f));
     }
     else if (texProperty.name.Equals("_OcclusionMap"))
     {
         return(new Color(1f, 1f, 1f, 1f));
     }
     else if (texProperty.name.Equals("_EmissionMap"))
     {
         if (mat != null)
         {
             if (mat.HasProperty("_EmissionScaleUI"))
             {
                 //Standard shader has weird behavior if EmissionMap has never
                 //been set then no EmissionColorUI color picker. If has ever
                 //been set then is EmissionColorUI color picker.
                 if (mat.HasProperty("_EmissionColor") &&
                     mat.HasProperty("_EmissionColorUI"))
                 {
                     try
                     {
                         Color c1 = mat.GetColor("_EmissionColor");
                         Color c2 = mat.GetColor("_EmissionColorUI");
                         float f  = mat.GetFloat("_EmissionScaleUI");
                         if (c1 == new Color(0f, 0f, 0f, 0f) &&
                             c2 == new Color(1f, 1f, 1f, 1f))
                         {
                             //is virgin Emission values
                             return(new Color(f, f, f, f));
                         }
                         else   //non virgin Emission values
                         {
                             return(c2);
                         }
                     }
                     catch (Exception) { }
                 }
                 else
                 {
                     try
                     { //need try because can't garantee _Color is a color
                         float f = mat.GetFloat("_EmissionScaleUI");
                         return(new Color(f, f, f, f));
                     }
                     catch (Exception) { }
                 }
             }
         }
     }
     else if (texProperty.name.Equals("_DetailMask"))
     {
         return(new Color(0f, 0f, 0f, 0f));
     }
     return(new Color(1f, 1f, 1f, 0f));
 }
示例#4
0
        /// <summary>
        /// Джх╬ Atlas
        /// </summary>
        /// <returns></returns>
        public Texture2D DoRenderAtlas(GameObject gameObject,
                                       int width,
                                       int height,
                                       int padding,
                                       Rect[] rss,
                                       List <MaterialPropTexturesSet> textureSetss,
                                       int indexOfTexSetToRenders,
                                       ShaderTextureProperty texPropertyname,
                                       TextureCombinerNonTextureProperties resultMaterialTextureBlender,
                                       bool isNormalMap,
                                       bool fixOutOfBoundsUVs,
                                       bool considerNonTextureProperties,
                                       TextureCombineHandler texCombiner)
        {
            textureSets           = textureSetss;
            indexOfTexSetToRender = indexOfTexSetToRenders;
            _texPropertyName      = texPropertyname;
            _padding                      = padding;
            _isNormalMap                  = isNormalMap;
            _fixOutOfBoundsUVs            = fixOutOfBoundsUVs;
            _resultMaterialTextureBlender = resultMaterialTextureBlender;
            rs = rss;
            Shader s;

            if (_isNormalMap)
            {
                s = Shader.Find("MeshBaker/NormalMapShader");
            }
            else
            {
                s = Shader.Find("MeshBaker/AlbedoShader");
            }
            if (s == null)
            {
                Debug.LogError("Could not find shader for RenderTexture. Try reimporting mesh baker");
                return(null);
            }
            mat = new Material(s);
            _destinationTexture            = new RenderTexture(width, height, 24, RenderTextureFormat.ARGB32);
            _destinationTexture.filterMode = FilterMode.Point;

            myCamera = gameObject.GetComponent <Camera>();
            myCamera.orthographic     = true;
            myCamera.orthographicSize = height >> 1;
            myCamera.aspect           = ((float)width) / height;
            myCamera.targetTexture    = _destinationTexture;
            myCamera.clearFlags       = CameraClearFlags.Color;

            Transform camTransform = myCamera.GetComponent <Transform>();

            camTransform.localPosition = new Vector3(width / 2.0f, height / 2f, 3);
            camTransform.localRotation = Quaternion.Euler(0, 180, 180);

            _doRenderAtlas = true;
            Debug.Log(string.Format("Begin Camera.Render destTex w={0} h={1} camPos={2} camSize={3} camAspect={4}",
                                    width, height, camTransform.localPosition, myCamera.orthographicSize, myCamera.aspect.ToString("f5")));
            //This triggers the OnRenderObject callback
            myCamera.Render();
            _doRenderAtlas = false;

            MeshBakerUtility.Destroy(mat);
            MeshBakerUtility.Destroy(_destinationTexture);

            Debug.Log("Finished Camera.Render ");

            Texture2D tempTex = targTex;

            targTex = null;
            return(tempTex);
        }
示例#5
0
        private void CopyScaledAndTiledToAtlas(MaterialPropTexturesSet texSet,
                                               MaterialPropTexture source,
                                               Vector2 obUVoffset,
                                               Vector2 obUVscale,
                                               Rect rec,
                                               ShaderTextureProperty texturePropertyName,
                                               TextureCombinerNonTextureProperties resultMatTexBlender,
                                               bool yIsFlipped)
        {
            Rect r = rec;

            myCamera.backgroundColor = resultMatTexBlender.GetColorForTemporaryTexture(texSet.matsAndGOs.mats[0].mat, texturePropertyName);
            //yIsFlipped = true;
            //if (yIsFlipped)
            //{
            //}
            r.y       = 1f - (r.y + r.height); // DrawTexture uses topLeft 0,0, Texture2D uses bottomLeft 0,0
            r.x      *= _destinationTexture.width;
            r.y      *= _destinationTexture.height;
            r.width  *= _destinationTexture.width;
            r.height *= _destinationTexture.height;

            Rect rPadded = r;

            rPadded.x      -= _padding;
            rPadded.y      -= _padding;
            rPadded.width  += _padding * 2;
            rPadded.height += _padding * 2;

            Rect targPr   = new Rect();
            Rect srcPrTex = texSet.ts[indexOfTexSetToRender].GetEncapsulatingSamplingRect().GetRect();

            if (!_fixOutOfBoundsUVs)
            {
                Debug.Assert(source.matTilingRect.GetRect() == texSet.ts[indexOfTexSetToRender].GetEncapsulatingSamplingRect().GetRect());
            }
            Texture2D tex = source.GetTexture2D();

            /*
             * if (_considerNonTextureProperties && resultMatTexBlender != null)
             * {
             *  if (LOG_LEVEL >= MB2_LogLevel.trace) Debug.Log(string.Format("Blending texture {0} mat {1} with non-texture properties using TextureBlender {2}", tex.name, texSet.mats[0].mat, resultMatTexBlender));
             *
             *  resultMatTexBlender.OnBeforeTintTexture(texSet.mats[0].mat, texturePropertyName.name);
             *  //combine the tintColor with the texture
             *  tex = combiner._createTextureCopy(tex);
             *  for (int i = 0; i < tex.height; i++)
             *  {
             *      Color[] cs = tex.GetPixels(0, i, tex.width, 1);
             *      for (int j = 0; j < cs.Length; j++)
             *      {
             *          cs[j] = resultMatTexBlender.OnBlendTexturePixel(texturePropertyName.name, cs[j]);
             *      }
             *      tex.SetPixels(0, i, tex.width, 1, cs);
             *  }
             *  tex.Apply();
             * }
             */


            //main texture
            TextureWrapMode oldTexWrapMode = tex.wrapMode;

            if (srcPrTex.width == 1f && srcPrTex.height == 1f && srcPrTex.x == 0f && srcPrTex.y == 0f)
            {
                //fixes bug where there is a dark line at the edge of the texture
                tex.wrapMode = TextureWrapMode.Clamp;
            }
            else
            {
                tex.wrapMode = TextureWrapMode.Repeat;
            }
            Debug.Log("DrawTexture tex=" + tex.name + " destRect=" + r + " srcRect=" + srcPrTex + " Mat=" + mat);
            //fill the padding first
            Rect srcPr = new Rect();

            //top margin
            srcPr.x       = srcPrTex.x;
            srcPr.y       = srcPrTex.y + 1 - 1f / tex.height;
            srcPr.width   = srcPrTex.width;
            srcPr.height  = 1f / tex.height;
            targPr.x      = r.x;
            targPr.y      = rPadded.y;
            targPr.width  = r.width;
            targPr.height = _padding;
            RenderTexture oldRT = RenderTexture.active;

            RenderTexture.active = _destinationTexture;
            Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);

            //bot margin
            srcPr.x       = srcPrTex.x;
            srcPr.y       = srcPrTex.y;
            srcPr.width   = srcPrTex.width;
            srcPr.height  = 1f / tex.height;
            targPr.x      = r.x;
            targPr.y      = r.y + r.height;
            targPr.width  = r.width;
            targPr.height = _padding;
            Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);


            //left margin
            srcPr.x       = srcPrTex.x;
            srcPr.y       = srcPrTex.y;
            srcPr.width   = 1f / tex.width;
            srcPr.height  = srcPrTex.height;
            targPr.x      = rPadded.x;
            targPr.y      = r.y;
            targPr.width  = _padding;
            targPr.height = r.height;
            Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);

            //right margin
            srcPr.x       = srcPrTex.x + 1f - 1f / tex.width;
            srcPr.y       = srcPrTex.y;
            srcPr.width   = 1f / tex.width;
            srcPr.height  = srcPrTex.height;
            targPr.x      = r.x + r.width;
            targPr.y      = r.y;
            targPr.width  = _padding;
            targPr.height = r.height;
            Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);


            //top left corner
            srcPr.x       = srcPrTex.x;
            srcPr.y       = srcPrTex.y + 1 - 1f / tex.height;
            srcPr.width   = 1f / tex.width;
            srcPr.height  = 1f / tex.height;
            targPr.x      = rPadded.x;
            targPr.y      = rPadded.y;
            targPr.width  = _padding;
            targPr.height = _padding;
            Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);

            //top right corner
            srcPr.x       = srcPrTex.x + 1f - 1f / tex.width;
            srcPr.y       = srcPrTex.y + 1 - 1f / tex.height;
            srcPr.width   = 1f / tex.width;
            srcPr.height  = 1f / tex.height;
            targPr.x      = r.x + r.width;
            targPr.y      = rPadded.y;
            targPr.width  = _padding;
            targPr.height = _padding;
            Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);

            //bot left corner
            srcPr.x       = srcPrTex.x;
            srcPr.y       = srcPrTex.y;
            srcPr.width   = 1f / tex.width;
            srcPr.height  = 1f / tex.height;
            targPr.x      = rPadded.x;
            targPr.y      = r.y + r.height;
            targPr.width  = _padding;
            targPr.height = _padding;
            Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);

            //bot right corner
            srcPr.x       = srcPrTex.x + 1f - 1f / tex.width;
            srcPr.y       = srcPrTex.y;
            srcPr.width   = 1f / tex.width;
            srcPr.height  = 1f / tex.height;
            targPr.x      = r.x + r.width;
            targPr.y      = r.y + r.height;
            targPr.width  = _padding;
            targPr.height = _padding;
            Graphics.DrawTexture(targPr, tex, srcPr, 0, 0, 0, 0, mat);

            //now the texture
            Graphics.DrawTexture(r, tex, srcPrTex, 0, 0, 0, 0, mat);
            RenderTexture.active = oldRT;
            tex.wrapMode         = oldTexWrapMode;
        }
示例#6
0
        public override IEnumerator CreateAtlases(ProgressUpdateDelegate progressInfo,
                                                  TexturePipelineData data,
                                                  TextureCombineHandler combiner,
                                                  AtlasPackingResult packedAtlasRects,
                                                  Texture2D[] atlases,
                                                  EditorMethodsInterface textureEditorMethods)
        {
            Debug.Assert(!data.IsOnlyOneTextureInAtlasReuseTextures());
            Rect[] uvRects = packedAtlasRects.rects;

            long estArea    = 0;
            int  atlasSizeX = 1;
            int  atlasSizeY = 1;

            uvRects = null;
            for (int propIdx = 0; propIdx < data.numAtlases; propIdx++)
            {
                //-----------------------
                ShaderTextureProperty prop  = data.texPropertyNames[propIdx];
                Texture2D             atlas = null;
                if (!TextureCombinerPipeline._ShouldWeCreateAtlasForThisProperty(propIdx, data._considerNonTextureProperties, data.allTexturesAreNullAndSameColor))
                {
                    atlas = null;
                }
                else
                {
                    Debug.LogWarning("Beginning loop " + propIdx + " num temporary textures " + combiner._getNumTemporaryTextures());
                    TextureCombinerPackerBase.CreateTemporaryTexturesForAtlas(data.distinctMaterialTextures, combiner, propIdx, data);
                    Texture2D[] texToPack = new Texture2D[data.distinctMaterialTextures.Count];
                    for (int texSetIdx = 0; texSetIdx < data.distinctMaterialTextures.Count; texSetIdx++)
                    {
                        MaterialPropTexturesSet txs = data.distinctMaterialTextures[texSetIdx];
                        int       tWidth            = txs.idealWidth;
                        int       tHeight           = txs.idealHeight;
                        Texture2D tx = txs.ts[propIdx].GetTexture2D();
                        if (progressInfo != null)
                        {
                            progressInfo("Adjusting for scale and offset " + tx, .01f);
                        }

                        if (textureEditorMethods != null)
                        {
                            textureEditorMethods.SetReadWriteFlag(tx, true, true);
                        }

                        tx = GetAdjustedForScaleAndOffset2(prop.name, txs.ts[propIdx], txs.obUVoffset, txs.obUVscale, data, combiner);
                        //create a resized copy if necessary
                        if (tx.width != tWidth || tx.height != tHeight)
                        {
                            if (progressInfo != null)
                            {
                                progressInfo("Resizing texture '" + tx + "'", .01f);
                            }
                            Debug.LogWarning("Copying and resizing texture " + prop.name + " from " + tx.width + "x" + tx.height + " to " + tWidth + "x" + tHeight);
                            tx = combiner._resizeTexture(prop.name, (Texture2D)tx, tWidth, tHeight);
                        }

                        estArea += tx.width * tx.height;
                        if (data._considerNonTextureProperties)
                        {
                            //combine the tintColor with the texture
                            tx = combiner._createTextureCopy(prop.name, tx);
                            data.nonTexturePropertyBlender.TintTextureWithTextureCombiner(tx, data.distinctMaterialTextures[texSetIdx], prop);
                        }

                        texToPack[texSetIdx] = tx;
                    }

                    if (textureEditorMethods != null)
                    {
                        textureEditorMethods.CheckBuildSettings(estArea);
                    }

                    if (Math.Sqrt(estArea) > 3500f)
                    {
                        Debug.LogWarning("The maximum possible atlas size is 4096. Textures may be shrunk");
                    }

                    atlas = new Texture2D(1, 1, TextureFormat.ARGB32, true);
                    if (progressInfo != null)
                    {
                        progressInfo("Packing texture atlas " + prop.name, .25f);
                    }
                    if (propIdx == 0)
                    {
                        if (progressInfo != null)
                        {
                            progressInfo("Estimated min size of atlases: " + Math.Sqrt(estArea).ToString("F0"), .1f);
                        }
                        Debug.Log("Estimated atlas minimum size:" + Math.Sqrt(estArea).ToString("F0"));
                        int maxAtlasSize = 4096;
                        uvRects = atlas.PackTextures(texToPack, data._atlasPadding, maxAtlasSize, false);
                        Debug.Log("After pack textures atlas size " + atlas.width + " " + atlas.height);
                        atlasSizeX = atlas.width;
                        atlasSizeY = atlas.height;
                        atlas.Apply();
                    }
                    else
                    {
                        if (progressInfo != null)
                        {
                            progressInfo("Copying Textures Into: " + prop.name, .1f);
                        }
                        atlas = _copyTexturesIntoAtlas(texToPack, data._atlasPadding, uvRects, atlasSizeX, atlasSizeY, combiner);
                    }
                }

                atlases[propIdx] = atlas;
                //----------------------

                if (data._saveAtlasesAsAssets && textureEditorMethods != null)
                {
                    textureEditorMethods.SaveAtlasToAssetDatabase(atlases[propIdx], prop, propIdx, data.resultMaterial);
                }
                data.resultMaterial.SetTextureOffset(prop.name, Vector2.zero);
                data.resultMaterial.SetTextureScale(prop.name, Vector2.one);
                combiner._destroyTemporaryTextures(prop.name);
                GC.Collect();
            }
            packedAtlasRects.rects = uvRects;
            yield break;
        }
 internal Color GetColorForTemporaryTexture(Material matIfBlender, ShaderTextureProperty texProperty)
 {
     return(_nonTexturePropertiesBlender.GetColorForTemporaryTexture(matIfBlender, texProperty));
 }
        /// <summary>
        /// 收集材质参数名称
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        internal static bool _CollectPropertyNames(TexturePipelineData data)
        {
            //try custom properties remove duplicates
            //尝试删除自定义属性的重复项
            for (int i = 0; i < data.texPropertyNames.Count; i++)
            {
                ShaderTextureProperty s = data._customShaderPropNames.Find(x => x.name.Equals(data.texPropertyNames[i].name));
                if (s != null)
                {
                    data._customShaderPropNames.Remove(s);
                }
            }

            Material m = data.resultMaterial;

            if (m == null)
            {
                Debug.LogError("合并材质为空。");
                return(false);
            }

            //Collect the property names for the textures
            for (int i = 0; i < shaderTexPropertyNames.Length; i++)
            {
                if (m.HasProperty(shaderTexPropertyNames[i].name))
                {
                    if (!data.texPropertyNames.Contains(shaderTexPropertyNames[i]))
                    {
                        data.texPropertyNames.Add(shaderTexPropertyNames[i]);
                    }
                    if (m.GetTextureOffset(shaderTexPropertyNames[i].name) != new Vector2(0f, 0f))
                    {
                        Debug.LogWarning("Result material has non-zero offset. This is may be incorrect.");
                    }
                    if (m.GetTextureScale(shaderTexPropertyNames[i].name) != new Vector2(1f, 1f))
                    {
                        Debug.LogWarning("Result material should have tiling of 1,1");
                    }
                }
            }

            for (int i = 0; i < data._customShaderPropNames.Count; i++)
            {
                if (m.HasProperty(data._customShaderPropNames[i].name))
                {
                    data.texPropertyNames.Add(data._customShaderPropNames[i]);
                    if (m.GetTextureOffset(data._customShaderPropNames[i].name) != new Vector2(0f, 0f))
                    {
                        Debug.LogWarning("Result material has non-zero offset. This is probably incorrect.");
                    }
                    if (m.GetTextureScale(data._customShaderPropNames[i].name) != new Vector2(1f, 1f))
                    {
                        Debug.LogWarning("Result material should probably have tiling of 1,1.");
                    }
                }
                else
                {
                    Debug.LogWarning("Result material shader does not use property " +
                                     data._customShaderPropNames[i].name + " in the list of custom shader property names");
                }
            }
            return(true);
        }
 internal Texture2D TintTextureWithTextureCombiner(Texture2D t, MaterialPropTexturesSet sourceMaterial, ShaderTextureProperty shaderPropertyName)
 {
     return(_nonTexturePropertiesBlender.TintTextureWithTextureCombiner(t, sourceMaterial, shaderPropertyName));
 }
 public Color GetColorForTemporaryTexture(Material matIfBlender, ShaderTextureProperty texProperty)
 {
     return(resultMaterialTextureBlender.GetColorIfNoTexture(matIfBlender, texProperty));
 }
            public Color GetColorAsItWouldAppearInAtlasIfNoTexture(Material matIfBlender, ShaderTextureProperty texProperty)
            {
                resultMaterialTextureBlender.OnBeforeTintTexture(matIfBlender, texProperty.name);
                Color c = GetColorForTemporaryTexture(matIfBlender, texProperty);

                return(resultMaterialTextureBlender.OnBlendTexturePixel(texProperty.name, c));
            }
 public Texture2D TintTextureWithTextureCombiner(Texture2D t, MaterialPropTexturesSet sourceMaterial, ShaderTextureProperty shaderPropertyName)
 {
     Debug.Assert(resultMaterialTextureBlender != null);
     resultMaterialTextureBlender.OnBeforeTintTexture(sourceMaterial.matsAndGOs.mats[0].mat, shaderPropertyName.name);
     Debug.Log(string.Format("Blending texture {0} mat {1} with non-texture properties using TextureBlender {2}", t.name, sourceMaterial.matsAndGOs.mats[0].mat, resultMaterialTextureBlender));
     for (int i = 0; i < t.height; i++)
     {
         Color[] cs = t.GetPixels(0, i, t.width, 1);
         for (int j = 0; j < cs.Length; j++)
         {
             cs[j] = resultMaterialTextureBlender.OnBlendTexturePixel(shaderPropertyName.name, cs[j]);
         }
         t.SetPixels(0, i, t.width, 1, cs);
     }
     t.Apply();
     return(t);
 }
 public Color GetColorAsItWouldAppearInAtlasIfNoTexture(Material matIfBlender, ShaderTextureProperty texProperty)
 {
     Debug.Assert(false, "Should never be called");
     return(Color.white);
 }
 public Texture2D TintTextureWithTextureCombiner(Texture2D t, MaterialPropTexturesSet sourceMaterial, ShaderTextureProperty shaderPropertyName)
 {
     Debug.Assert(_textureProperties._considerNonTextureProperties == false);
     Debug.LogError("TintTextureWithTextureCombiner should never be called if resultMaterialTextureBlender is null");
     return(t);
 }
        internal static IEnumerator CopyScaledAndTiledToAtlas(MaterialPropTexture source, MaterialPropTexturesSet sourceMaterial,
                                                              ShaderTextureProperty shaderPropertyName, DRect srcSamplingRect, int targX, int targY, int targW, int targH,
                                                              AtlasPadding padding,
                                                              Color[][] atlasPixels, bool isNormalMap,
                                                              TexturePipelineData data,
                                                              TextureCombineHandler combiner,
                                                              ProgressUpdateDelegate progressInfo = null)
        {
            //HasFinished = false;
            Texture2D t = source.GetTexture2D();

            Debug.Log(string.Format("CopyScaledAndTiledToAtlas: {0} inAtlasX={1} inAtlasY={2} inAtlasW={3} inAtlasH={4} paddX={5} paddY={6} srcSamplingRect={7}",
                                    t, targX, targY, targW, targH, padding.leftRight, padding.topBottom, srcSamplingRect));

            float newWidth  = targW;
            float newHeight = targH;
            float scx       = (float)srcSamplingRect.width;
            float scy       = (float)srcSamplingRect.height;
            float ox        = (float)srcSamplingRect.x;
            float oy        = (float)srcSamplingRect.y;
            int   w         = (int)newWidth;
            int   h         = (int)newHeight;

            if (data._considerNonTextureProperties)
            {
                t = combiner._createTextureCopy(shaderPropertyName.name, t);
                t = data.nonTexturePropertyBlender.TintTextureWithTextureCombiner(t, sourceMaterial, shaderPropertyName);
            }
            for (int i = 0; i < w; i++)
            {
                if (progressInfo != null && w > 0)
                {
                    progressInfo("CopyScaledAndTiledToAtlas " + (((float)i / (float)w) * 100f).ToString("F0"), .2f);
                }
                for (int j = 0; j < h; j++)
                {
                    float u = i / newWidth * scx + ox;
                    float v = j / newHeight * scy + oy;
                    atlasPixels[targY + j][targX + i] = t.GetPixelBilinear(u, v);
                }
            }

            //bleed the border colors into the padding
            for (int i = 0; i < w; i++)
            {
                for (int j = 1; j <= padding.topBottom; j++)
                {
                    //top margin
                    atlasPixels[(targY - j)][targX + i] = atlasPixels[(targY)][targX + i];
                    //bottom margin
                    atlasPixels[(targY + h - 1 + j)][targX + i] = atlasPixels[(targY + h - 1)][targX + i];
                }
            }
            for (int j = 0; j < h; j++)
            {
                for (int i = 1; i <= padding.leftRight; i++)
                {
                    //left margin
                    atlasPixels[(targY + j)][targX - i] = atlasPixels[(targY + j)][targX];
                    //right margin
                    atlasPixels[(targY + j)][targX + w + i - 1] = atlasPixels[(targY + j)][targX + w - 1];
                }
            }
            //corners
            for (int i = 1; i <= padding.leftRight; i++)
            {
                for (int j = 1; j <= padding.topBottom; j++)
                {
                    atlasPixels[(targY - j)][targX - i]                 = atlasPixels[targY][targX];
                    atlasPixels[(targY + h - 1 + j)][targX - i]         = atlasPixels[(targY + h - 1)][targX];
                    atlasPixels[(targY + h - 1 + j)][targX + w + i - 1] = atlasPixels[(targY + h - 1)][targX + w - 1];
                    atlasPixels[(targY - j)][targX + w + i - 1]         = atlasPixels[targY][targX + w - 1];
                    yield return(null);
                }
                yield return(null);
            }
            yield break;
        }
 internal Color GetColorAsItWouldAppearInAtlasIfNoTexture(Material matIfBlender, ShaderTextureProperty texProperty)
 {
     return(_nonTexturePropertiesBlender.GetColorAsItWouldAppearInAtlasIfNoTexture(matIfBlender, texProperty));
 }
        public override IEnumerator CreateAtlases(ProgressUpdateDelegate progressInfo,
                                                  TexturePipelineData data,
                                                  TextureCombineHandler combiner,
                                                  AtlasPackingResult packedAtlasRects,
                                                  Texture2D[] atlases,
                                                  EditorMethodsInterface textureEditorMethods)
        {
            Rect[] uvRects = packedAtlasRects.rects;

            int atlasSizeX = packedAtlasRects.atlasX;
            int atlasSizeY = packedAtlasRects.atlasY;

            Debug.Log("Generated atlas will be " + atlasSizeX + "x" + atlasSizeY);

            for (int propIdx = 0; propIdx < data.numAtlases; propIdx++)
            {
                Texture2D             atlas    = null;
                ShaderTextureProperty property = data.texPropertyNames[propIdx];
                if (!TextureCombinerPipeline._ShouldWeCreateAtlasForThisProperty(propIdx, data._considerNonTextureProperties, data.allTexturesAreNullAndSameColor))
                {
                    atlas = null;
                    Debug.Log("=== Not creating atlas for " + property.name + " because textures are null and default value parameters are the same.");
                }
                else
                {
                    Debug.Log("=== Creating atlas for " + property.name);
                    GC.Collect();
                    CreateTemporaryTexturesForAtlas(data.distinctMaterialTextures, combiner, propIdx, data);

                    //use a jagged array because it is much more efficient in memory
                    Color[][] atlasPixels = new Color[atlasSizeY][];
                    for (int j = 0; j < atlasPixels.Length; j++)
                    {
                        atlasPixels[j] = new Color[atlasSizeX];
                    }

                    bool isNormalMap = false;
                    if (property.isNormalMap)
                    {
                        isNormalMap = true;
                    }

                    for (int texSetIdx = 0; texSetIdx < data.distinctMaterialTextures.Count; texSetIdx++)
                    {
                        MaterialPropTexturesSet texSet = data.distinctMaterialTextures[texSetIdx];
                        MaterialPropTexture     matTex = texSet.ts[propIdx];
                        string s = "Creating Atlas '" + property.name + "' texture " + matTex.GetTexName();
                        if (progressInfo != null)
                        {
                            progressInfo(s, .01f);
                        }
                        Debug.Log(string.Format("Adding texture {0} to atlas {1} for texSet {2} srcMat {3}", matTex.GetTexName(), property.name, texSetIdx, texSet.matsAndGOs.mats[0].GetMaterialName()));

                        Rect      r  = uvRects[texSetIdx];
                        Texture2D t  = texSet.ts[propIdx].GetTexture2D();
                        int       x  = Mathf.RoundToInt(r.x * atlasSizeX);
                        int       y  = Mathf.RoundToInt(r.y * atlasSizeY);
                        int       ww = Mathf.RoundToInt(r.width * atlasSizeX);
                        int       hh = Mathf.RoundToInt(r.height * atlasSizeY);
                        if (ww == 0 || hh == 0)
                        {
                            Debug.LogError("Image in atlas has no height or width " + r);
                        }
                        if (progressInfo != null)
                        {
                            progressInfo(s + " set ReadWrite flag", .01f);
                        }
                        if (textureEditorMethods != null)
                        {
                            textureEditorMethods.SetReadWriteFlag(t, true, true);
                        }
                        if (progressInfo != null)
                        {
                            progressInfo(s + "Copying to atlas: '" + matTex.GetTexName() + "'", .02f);
                        }
                        DRect samplingRect = texSet.ts[propIdx].GetEncapsulatingSamplingRect();
                        Debug.Assert(!texSet.ts[propIdx].isNull, string.Format("Adding texture {0} to atlas {1} for texSet {2} srcMat {3}",
                                                                               matTex.GetTexName(), property.name, texSetIdx, texSet.matsAndGOs.mats[0].GetMaterialName()));
                        yield return(CopyScaledAndTiledToAtlas(texSet.ts[propIdx],
                                                               texSet,
                                                               property,
                                                               samplingRect,
                                                               x,
                                                               y,
                                                               ww,
                                                               hh,
                                                               packedAtlasRects.padding[texSetIdx],
                                                               atlasPixels,
                                                               isNormalMap,
                                                               data,
                                                               combiner,
                                                               progressInfo));
                    }

                    yield return(data.numAtlases);

                    if (progressInfo != null)
                    {
                        progressInfo("Applying changes to atlas: '" + property.name + "'", .03f);
                    }
                    atlas = new Texture2D(atlasSizeX, atlasSizeY, TextureFormat.ARGB32, true);
                    for (int j = 0; j < atlasPixels.Length; j++)
                    {
                        atlas.SetPixels(0, j, atlasSizeX, 1, atlasPixels[j]);
                    }

                    atlas.Apply();
                    Debug.Log("Saving atlas " + property.name + " w=" + atlas.width + " h=" + atlas.height);
                }

                atlases[propIdx] = atlas;
                if (progressInfo != null)
                {
                    progressInfo("Saving atlas: '" + property.name + "'", .04f);
                }
                if (data._saveAtlasesAsAssets && textureEditorMethods != null)
                {
                    textureEditorMethods.SaveAtlasToAssetDatabase(atlases[propIdx], data.texPropertyNames[propIdx], propIdx, data.resultMaterial);
                }
                else
                {
                    data.resultMaterial.SetTexture(data.texPropertyNames[propIdx].name, atlases[propIdx]);
                }

                data.resultMaterial.SetTextureOffset(data.texPropertyNames[propIdx].name, Vector2.zero);
                data.resultMaterial.SetTextureScale(data.texPropertyNames[propIdx].name, Vector2.one);
                combiner._destroyTemporaryTextures(data.texPropertyNames[propIdx].name);
            }

            yield break;
        }
        /// <summary>
        ///  Texture 合并管线第 3 步,创建 Atlas 并保存资源
        /// </summary>
        /// <returns></returns>
        internal static IEnumerator __Step3_BuildAndSaveAtlasesAndStoreResults(ProgressUpdateDelegate progressInfo,
                                                                               CombineTexturesIntoAtlasesCoroutineResult result,
                                                                               TexturePipelineData data,
                                                                               TextureCombineHandler combiner,
                                                                               ITextureCombinerPacker packer,
                                                                               AtlasPackingResult atlasPackingResult,
                                                                               EditorMethodsInterface textureEditorMethods,
                                                                               AtlasesAndRects resultAtlasesAndRects)
        {
            //run the garbage collector to free up as much memory as possible before bake to reduce MissingReferenceException problems
            GC.Collect();
            Texture2D[] atlases = new Texture2D[data.numAtlases];
            //StringBuilder report = GenerateReport(data);

            //创建图集
            yield return(packer.CreateAtlases(progressInfo, data, combiner, atlasPackingResult, atlases, textureEditorMethods));

            data.nonTexturePropertyBlender.AdjustNonTextureProperties(data.resultMaterial, data.texPropertyNames, data.distinctMaterialTextures, textureEditorMethods);

            if (data.distinctMaterialTextures.Count > 0)
            {
                data.distinctMaterialTextures[0].AdjustResultMaterialNonTextureProperties(data.resultMaterial, data.texPropertyNames);
            }

            //结果报告
            //if (progressInfo != null)
            //    progressInfo("Building Report", .7f);
            ////report on atlases created
            //StringBuilder atlasMessage = new StringBuilder();
            //atlasMessage.AppendLine("---- Atlases ------");
            //for (int i = 0; i < data.numAtlases; i++)
            //{
            //    if (atlases[i] != null)
            //    {
            //        atlasMessage.AppendLine("Created Atlas For: " + data.texPropertyNames[i].name + " h=" + atlases[i].height + " w=" + atlases[i].width);
            //    }
            //    else if (!_ShouldWeCreateAtlasForThisProperty(i, data._considerNonTextureProperties, data.allTexturesAreNullAndSameColor))
            //    {
            //        atlasMessage.AppendLine("Did not create atlas for " + data.texPropertyNames[i].name + " because all source textures were null.");
            //    }
            //}
            //report.Append(atlasMessage.ToString());

            List <MaterialAndUVRect> mat2rect_map = new List <MaterialAndUVRect>();

            for (int i = 0; i < data.distinctMaterialTextures.Count; i++)
            {
                MaterialPropTexturesSet        texSet = data.distinctMaterialTextures[i];
                List <MatAndTransformToMerged> mats   = texSet.matsAndGOs.mats;
                Rect allPropsUseSameTiling_encapsulatingSamplingRect;
                Rect propsUseDifferntTiling_obUVRect;
                texSet.GetRectsForTextureBakeResults(out allPropsUseSameTiling_encapsulatingSamplingRect, out propsUseDifferntTiling_obUVRect);
                for (int j = 0; j < mats.Count; j++)
                {
                    Rect allPropsUseSameTiling_sourceMaterialTiling = texSet.GetMaterialTilingRectForTextureBakerResults(j);
                    MaterialAndUVRect key = new MaterialAndUVRect(
                        mats[j].mat,
                        atlasPackingResult.rects[i],
                        texSet.allTexturesUseSameMatTiling,
                        allPropsUseSameTiling_sourceMaterialTiling,
                        allPropsUseSameTiling_encapsulatingSamplingRect,
                        propsUseDifferntTiling_obUVRect,
                        texSet.tilingTreatment,
                        mats[j].objName);
                    if (!mat2rect_map.Contains(key))
                    {
                        mat2rect_map.Add(key);
                    }
                }
            }

            resultAtlasesAndRects.atlases             = atlases;                                               // one per texture on result shader
            resultAtlasesAndRects.texPropertyNames    = ShaderTextureProperty.GetNames(data.texPropertyNames); // one per texture on source shader
            resultAtlasesAndRects.originMatToRect_map = mat2rect_map;

            if (progressInfo != null)
            {
                progressInfo("Restoring Texture Formats & Read Flags", .8f);
            }
            combiner._destroyAllTemporaryTextures();
            if (textureEditorMethods != null)
            {
                textureEditorMethods.RestoreReadFlagsAndFormats(progressInfo);
            }

            //if (report != null)
            //    Debug.Log(report.ToString());

            yield break;
        }