Beispiel #1
0
        /// <summary>
        ///  Texture 合并管线第 3 步,创建 Atlas 并保存资源
        /// </summary>
        /// <returns></returns>
        internal static void Step3_BuildAndSaveAtlasesAndStoreResults(
            TextureCombinePipelineData data,
            TextureCombineHandler combiner,
            ITextureCombineAtlasPacker 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);

            //创建图集
            packer.CreateAtlases(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);
            }

            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;

            combiner._destroyAllTemporaryTextures();
        }
Beispiel #2
0
    public void RunTestHarness()
    {
        if (packerType == PackerType.regular)
        {
            texturePacker = new MB2_TexturePackerRegular();
        }
        else if (packerType == PackerType.horizontal)
        {
            MB2_TexturePackerHorizontalVert tp = new MB2_TexturePackerHorizontalVert();
            tp.packingOrientation = MB2_TexturePackerHorizontalVert.TexturePackingOrientation.horizontal;
            texturePacker         = tp;
        }
        else if (packerType == PackerType.vertical)
        {
            MB2_TexturePackerHorizontalVert tp = new MB2_TexturePackerHorizontalVert();
            tp.packingOrientation = MB2_TexturePackerHorizontalVert.TexturePackingOrientation.vertical;
            texturePacker         = tp;
        }

        texturePacker.atlasMustBePowerOfTwo = atlasMustBePowerOfTwo;
        texturePacker.LOG_LEVEL             = logLevel;

        rs = texturePacker.GetRects(imgsToAdd, maxDim, padding, doMultiAtlas);
        if (rs != null)
        {
            Debug.Log("NumAtlas= " + rs.Length);
            for (int i = 0; i < rs.Length; i++)
            {
                Debug.Log("AtlasSize " + rs[i].atlasX + " mxY= " + rs[i].atlasY);
                for (int j = 0; j < rs[i].rects.Length; j++)
                {
                    Rect r = rs[i].rects[j];
                    r.x      *= rs[i].atlasX;
                    r.y      *= rs[i].atlasY;
                    r.width  *= rs[i].atlasX;
                    r.height *= rs[i].atlasY;
                    Debug.Log(r.ToString("f5"));
                }
                Vector2            offset = new Vector2((i * 1.5f) * maxDim, 0);
                AtlasPackingResult apr    = rs[i];
                Vector2            center = new Vector2(offset.x + apr.atlasX / 2, offset.y + apr.atlasY / 2);
                Vector2            sz     = new Vector2(apr.atlasX, apr.atlasY);

                Debug.Log("===============");
            }
            if (rs.Length > 0)
            {
                res = "mxX= " + rs[0].atlasX + " mxY= " + rs[0].atlasY;
            }
        }
        else
        {
            res = "ERROR: PACKING FAILED";
        }
    }
 private void OnDrawGizmos()
 {
     if (rs != null)
     {
         for (int i = 0; i < rs.Length; i++)
         {
             Vector2            offset = new Vector2((i * 1.5f) * maxDim, 0);
             AtlasPackingResult apr    = rs[i];
             Vector2            center = new Vector2(offset.x + apr.atlasX / 2, offset.y + apr.atlasY / 2);
             Vector2            sz     = new Vector2(apr.atlasX, apr.atlasY);
             Gizmos.DrawWireCube(center, sz);
             for (int j = 0; j < rs[i].rects.Length; j++)
             {
                 Rect r = rs[i].rects[j];
                 Gizmos.color = new Color(Random.value, Random.value, Random.value);
                 center       = new Vector2(offset.x + (r.x + r.width / 2f) * rs[i].atlasX, offset.y + (r.y + r.height / 2f) * rs[i].atlasY);
                 Vector2 szz = new Vector2(r.width * rs[i].atlasX, r.height * rs[i].atlasY);
                 Gizmos.DrawCube(center, szz);
             }
         }
     }
 }
Beispiel #4
0
        public override void CreateAtlases(
            TextureCombinePipelineData 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 (!TextureCombinePipeline.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();

                        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 (textureEditorMethods != null)
                        {
                            textureEditorMethods.SetReadWriteFlag(t, true, true);
                        }
                        DRect samplingRect = texSet.ts[propIdx].GetEncapsulatingSamplingRect();
                        CopyScaledAndTiledToAtlas(texSet.ts[propIdx],
                                                  texSet,
                                                  property,
                                                  samplingRect,
                                                  x,
                                                  y,
                                                  ww,
                                                  hh,
                                                  packedAtlasRects.padding[texSetIdx],
                                                  atlasPixels,
                                                  isNormalMap,
                                                  data,
                                                  combiner);
                    }

                    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 (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);
            }
        }
 public abstract void CreateAtlases(TextureCombinePipelineData data,
                                    TextureCombineHandler combiner,
                                    AtlasPackingResult packedAtlasRects,
                                    Texture2D[] atlases,
                                    EditorMethodsInterface textureEditorMethods);