internal static StringBuilder GenerateReport(TexturePipelineData data) { //generate report want to do this before StringBuilder report = new StringBuilder(); if (data.numAtlases > 0) { report = new StringBuilder(); report.AppendLine("Report"); for (int i = 0; i < data.distinctMaterialTextures.Count; i++) { MaterialPropTexturesSet txs = data.distinctMaterialTextures[i]; report.AppendLine("----------"); report.Append("This set of textures will be resized to:" + txs.idealWidth + "x" + txs.idealHeight + "\n"); for (int j = 0; j < txs.ts.Length; j++) { if (!txs.ts[j].isNull) { report.Append(" [" + data.texPropertyNames[j].name + " " + txs.ts[j].GetTexName() + " " + txs.ts[j].width + "x" + txs.ts[j].height + "]"); if (txs.ts[j].matTilingRect.size != Vector2.one || txs.ts[j].matTilingRect.min != Vector2.zero) { report.AppendFormat(" material scale {0} offset{1} ", txs.ts[j].matTilingRect.size.ToString("G4"), txs.ts[j].matTilingRect.min.ToString("G4")); } if (txs.obUVscale != Vector2.one || txs.obUVoffset != Vector2.zero) { report.AppendFormat(" obUV scale {0} offset{1} ", txs.obUVscale.ToString("G4"), txs.obUVoffset.ToString("G4")); } report.AppendLine(""); } else { report.Append(" [" + data.texPropertyNames[j].name + " null "); if (!TextureCombinerPipeline._ShouldWeCreateAtlasForThisProperty(j, data._considerNonTextureProperties, data.allTexturesAreNullAndSameColor)) { report.Append("no atlas will be created all textures null]\n"); } else { report.AppendFormat("a 16x16 texture will be created]\n"); } } } report.AppendLine(""); report.Append("Materials using:"); for (int j = 0; j < txs.matsAndGOs.mats.Count; j++) { report.Append(txs.matsAndGOs.mats[j].mat.name + ", "); } report.AppendLine(""); } } return(report); }
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; }
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; }
public IEnumerator CreateAtlases(ProgressUpdateDelegate progressInfo, TexturePipelineData data, TextureCombineHandler combiner, AtlasPackingResult packedAtlasRects, Texture2D[] atlases, EditorMethodsInterface textureEditorMethods) { Debug.Assert(!data.IsOnlyOneTextureInAtlasReuseTextures()); Rect[] uvRects = packedAtlasRects.rects; int atlasSizeX = packedAtlasRects.atlasX; int atlasSizeY = packedAtlasRects.atlasY; Debug.Log("Generated atlas will be " + atlasSizeX + "x" + atlasSizeY); //create a game object GameObject renderAtlasesGO = null; try { renderAtlasesGO = new GameObject("MBrenderAtlasesGO"); AtlasPackerRenderTexture atlasRenderTexture = renderAtlasesGO.AddComponent <AtlasPackerRenderTexture>(); renderAtlasesGO.AddComponent <Camera>(); if (data._considerNonTextureProperties) { Debug.LogWarning("Blend Non-Texture Properties has limited functionality when used with Mesh Baker Texture Packer Fast."); } for (int propIdx = 0; propIdx < data.numAtlases; propIdx++) { Texture2D atlas = null; if (!TextureCombinerPipeline._ShouldWeCreateAtlasForThisProperty(propIdx, data._considerNonTextureProperties, data.allTexturesAreNullAndSameColor)) { atlas = null; Debug.Log("Not creating atlas for " + data.texPropertyNames[propIdx].name + " because textures are null and default value parameters are the same."); } else { GC.Collect(); TextureCombinerPackerBase.CreateTemporaryTexturesForAtlas(data.distinctMaterialTextures, combiner, propIdx, data); if (progressInfo != null) { progressInfo("Creating Atlas '" + data.texPropertyNames[propIdx].name + "'", .01f); } // =========== // configure it Debug.Log("About to render " + data.texPropertyNames[propIdx].name + " isNormal=" + data.texPropertyNames[propIdx].isNormalMap); atlasRenderTexture.width = atlasSizeX; atlasRenderTexture.height = atlasSizeY; atlasRenderTexture.padding = data._atlasPadding; atlasRenderTexture.rects = uvRects; atlasRenderTexture.textureSets = data.distinctMaterialTextures; atlasRenderTexture.indexOfTexSetToRender = propIdx; atlasRenderTexture.texPropertyName = data.texPropertyNames[propIdx]; atlasRenderTexture.isNormalMap = data.texPropertyNames[propIdx].isNormalMap; atlasRenderTexture.fixOutOfBoundsUVs = data._fixOutOfBoundsUVs; atlasRenderTexture.considerNonTextureProperties = data._considerNonTextureProperties; atlasRenderTexture.resultMaterialTextureBlender = data.nonTexturePropertyBlender; // call render on it atlas = atlasRenderTexture.OnRenderAtlas(combiner); // destroy it // ============= Debug.Log("Saving atlas " + data.texPropertyNames[propIdx].name + " w=" + atlas.width + " h=" + atlas.height + " id=" + atlas.GetInstanceID()); } atlases[propIdx] = atlas; if (progressInfo != null) { progressInfo("Saving atlas: '" + data.texPropertyNames[propIdx].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); // need to save atlases before doing this } } catch (Exception ex) { //Debug.LogError(ex); Debug.LogException(ex); } finally { if (renderAtlasesGO != null) { MeshBakerUtility.Destroy(renderAtlasesGO); } } yield break; }