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); }
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)); }
/// <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); }
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; }
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; }