public virtual IEnumerator ConvertTexturesToReadableFormats(ProgressUpdateDelegate progressInfo, CombineTexturesIntoAtlasesCoroutineResult result, TexturePipelineData data, TextureCombineHandler combiner, EditorMethodsInterface textureEditorMethods) { Debug.Assert(!data.IsOnlyOneTextureInAtlasReuseTextures()); //MakeProceduralTexturesReadable(progressInfo, result, data, combiner, textureEditorMethods, LOG_LEVEL); for (int i = 0; i < data.distinctMaterialTextures.Count; i++) { for (int j = 0; j < data.texPropertyNames.Count; j++) { MaterialPropTexture ts = data.distinctMaterialTextures[i].ts[j]; if (!ts.isNull) { if (textureEditorMethods != null) { Texture tx = ts.GetTexture2D(); if (progressInfo != null) { progressInfo(String.Format("Convert texture {0} to readable format ", tx), .5f); } textureEditorMethods.AddTextureFormat((Texture2D)tx, data.texPropertyNames[j].isNormalMap); } } } } yield break; }
public void CreateColoredTexToReplaceNull(string propName, int propIdx, bool considerMeshUVs, TextureCombineHandler combiner, Color col) { MaterialPropTexture matTex = ts[propIdx]; matTex.t = combiner._createTemporaryTexture(propName, 16, 16, TextureFormat.ARGB32, true); MeshBakerUtility.setSolidColor(matTex.GetTexture2D(), col); }
// used by Unity texture packer to handle tiled textures. // may create a new texture that has the correct tiling to handle fix out of bounds UVs internal static Texture2D GetAdjustedForScaleAndOffset2(string propertyName, MaterialPropTexture source, Vector2 obUVoffset, Vector2 obUVscale, TexturePipelineData data, TextureCombineHandler combiner) { Texture2D sourceTex = source.GetTexture2D(); if (source.matTilingRect.x == 0f && source.matTilingRect.y == 0f && source.matTilingRect.width == 1f && source.matTilingRect.height == 1f) { if (data._fixOutOfBoundsUVs) { if (obUVoffset.x == 0f && obUVoffset.y == 0f && obUVscale.x == 1f && obUVscale.y == 1f) { return(sourceTex); //no adjustment necessary } } else { return(sourceTex); //no adjustment necessary } } Vector2 dim = TextureCombinerPipeline.GetAdjustedForScaleAndOffset2Dimensions(source, obUVoffset, obUVscale, data); Debug.LogWarning("GetAdjustedForScaleAndOffset2: " + sourceTex + " " + obUVoffset + " " + obUVscale); float newWidth = dim.x; float newHeight = dim.y; float scx = (float)source.matTilingRect.width; float scy = (float)source.matTilingRect.height; float ox = (float)source.matTilingRect.x; float oy = (float)source.matTilingRect.y; if (data._fixOutOfBoundsUVs) { scx *= obUVscale.x; scy *= obUVscale.y; ox = (float)(source.matTilingRect.x * obUVscale.x + obUVoffset.x); oy = (float)(source.matTilingRect.y * obUVscale.y + obUVoffset.y); } Texture2D newTex = combiner._createTemporaryTexture(propertyName, (int)newWidth, (int)newHeight, TextureFormat.ARGB32, true); for (int i = 0; i < newTex.width; i++) { for (int j = 0; j < newTex.height; j++) { float u = i / newWidth * scx + ox; float v = j / newHeight * scy + oy; newTex.SetPixel(i, j, sourceTex.GetPixelBilinear(u, v)); } } newTex.Apply(); return(newTex); }
public IEnumerator CreateAtlases(ProgressUpdateDelegate progressInfo, TexturePipelineData data, TextureCombineHandler combiner, AtlasPackingResult packedAtlasRects, Texture2D[] atlases, EditorMethodsInterface textureEditorMethods) { Debug.Assert(data.IsOnlyOneTextureInAtlasReuseTextures()); Debug.Log("Only one image per atlas. Will re-use original texture"); for (int i = 0; i < data.numAtlases; i++) { MaterialPropTexture dmt = data.distinctMaterialTextures[0].ts[i]; atlases[i] = dmt.GetTexture2D(); data.resultMaterial.SetTexture(data.texPropertyNames[i].name, atlases[i]); data.resultMaterial.SetTextureScale(data.texPropertyNames[i].name, Vector2.one); data.resultMaterial.SetTextureOffset(data.texPropertyNames[i].name, Vector2.zero); } yield break; }
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; }
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 void OnRenderObject() { if (_doRenderAtlas) { //assett rs must be same length as textureSets; System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); bool yIsFlipped = YisFlipped(); for (int i = 0; i < rs.Length; i++) { MaterialPropTexture texInfo = textureSets[i].ts[indexOfTexSetToRender]; Texture2D tx = texInfo.GetTexture2D(); if (tx != null) { Debug.Log("Added " + tx + " to atlas w=" + tx.width + " h=" + tx.height + " offset=" + texInfo.matTilingRect.min + " scale=" + texInfo.matTilingRect.size + " rect=" + rs[i] + " padding=" + _padding); } CopyScaledAndTiledToAtlas(textureSets[i], texInfo, textureSets[i].obUVoffset, textureSets[i].obUVscale, rs[i], _texPropertyName, _resultMaterialTextureBlender, yIsFlipped); } sw.Stop(); sw.Start(); Debug.Log("Total time for Graphics.DrawTexture calls " + (sw.ElapsedMilliseconds).ToString("f5")); Debug.Log("Copying RenderTexture to Texture2D. destW" + _destinationTexture.width + " destH" + _destinationTexture.height); //Convert the RenderTexture to a Texture2D Texture2D tempTexture; tempTexture = new Texture2D(_destinationTexture.width, _destinationTexture.height, TextureFormat.ARGB32, true); RenderTexture oldRT = RenderTexture.active; RenderTexture.active = _destinationTexture; int xblocks = Mathf.CeilToInt(((float)_destinationTexture.width) / 512); int yblocks = Mathf.CeilToInt(((float)_destinationTexture.height) / 512); if (xblocks == 0 || yblocks == 0) { Debug.Log("Copying all in one shot"); tempTexture.ReadPixels(new Rect(0, 0, _destinationTexture.width, _destinationTexture.height), 0, 0, true); } else { if (yIsFlipped == false) { for (int x = 0; x < xblocks; x++) { for (int y = 0; y < yblocks; y++) { int xx = x * 512; int yy = y * 512; Rect r = new Rect(xx, yy, 512, 512); tempTexture.ReadPixels(r, x * 512, y * 512, true); } } } else { Debug.Log("Not OpenGL copying blocks"); for (int x = 0; x < xblocks; x++) { for (int y = 0; y < yblocks; y++) { int xx = x * 512; int yy = _destinationTexture.height - 512 - y * 512; Rect r = new Rect(xx, yy, 512, 512); tempTexture.ReadPixels(r, x * 512, y * 512, true); } } } } RenderTexture.active = oldRT; tempTexture.Apply(); Debug.Log("TempTexture "); if (tempTexture.height <= 16 && tempTexture.width <= 16) { _printTexture(tempTexture); } myCamera.targetTexture = null; RenderTexture.active = null; targTex = tempTexture; Debug.Log("Total time to copy RenderTexture to Texture2D " + (sw.ElapsedMilliseconds).ToString("f5")); } }