/// <summary> /// Generates the packed material map for an object /// </summary> public static void GeneratePackedMaterialMap(AlloyCustomImportObject settings, Texture2D target, string filePath) { var size = settings.GetOutputSize(); var normalMap = settings.NormalMapTexture; var useUnityGeneratedMipmaps = normalMap == null; int width = (int)size.x; int height = (int)size.y; int mipmapCount = 1; // When explicitly generating mip levels pick output count based on the largest input texture. if (!useUnityGeneratedMipmaps) { mipmapCount = GetMipmapCount(normalMap); for (int i = 0; i < 4; ++i) { if (settings.SelectedModes[i] != TextureValueChannelMode.Texture || settings.GetTexture(i) == null) { continue; } mipmapCount = Math.Max(mipmapCount, GetMipmapCount(settings.GetTexture(i))); } } // Adjust the dimensions of the output texture if necessary. if (target.width != width || target.height != height) { target.Resize(width, height); } if (!Mathf.IsPowerOfTwo(width) || !Mathf.IsPowerOfTwo(height)) { Debug.LogWarning( "Alloy: Texture resolution is not power of 2; will have issues generating correct mip maps if custom sizing is specified in generated texture platform settings."); } // Get readable input textures. var readableNormal = AlloyTextureReader.GetReadable(normalMap, true); var readableTextures = new Texture2D[settings.TexturesGUID.Length]; for (int i = 0; i < settings.TexturesGUID.Length; ++i) { if (settings.SelectedModes[i] != TextureValueChannelMode.Texture) { continue; } var settingsTex = settings.GetTexture(i); if (settingsTex == null) { readableTextures[i] = null; } else { readableTextures[i] = AlloyTextureReader.GetReadable(settingsTex, false); } } // Use renderer to sample mipmaps. try { var message = string.Format("Packing: \"{0}\"", settings.name); var progress = 1.0f; var bodyText = message; for (int mipLevel = 0; mipLevel < mipmapCount; mipLevel++) { if (mipmapCount > 1) { progress = (float)mipLevel / (mipmapCount - 1); bodyText = string.Format("{0} ({1})", message, progress.ToString("0%")); } EditorUtility.DisplayProgressBar("Building Packed maps...", bodyText, progress); // CPU Method - more reliable/consistent across GPUs, but slower. var normalCache = new AlloyTextureColorCache(readableNormal, target); UnityEngine.Profiling.Profiler.BeginSample("Read"); var texCache = readableTextures.Select(tex => new AlloyTextureColorCache(tex, target)).ToArray(); UnityEngine.Profiling.Profiler.EndSample(); AlloyPackerCompositor.CompositeMips(target, settings, texCache, normalCache, mipLevel); } } finally { EditorUtility.ClearProgressBar(); } // Clean up the readable textures. foreach (var texture in readableTextures) { Object.DestroyImmediate(texture); } Object.DestroyImmediate(readableNormal); // Update the texture's associated settings .asset object. settings.Width = width; settings.Height = height; settings.MaxResolution = 0; EditorUtility.SetDirty(settings); // Update the texture object. target.Apply(useUnityGeneratedMipmaps, false); }
/// <summary> /// Generates the packed material map for an object /// </summary> public static void GeneratePackedMaterialMap(AlloyCustomImportObject settings, Texture2D target, string filePath) { int mipmapCount = 1; Vector2 size = settings.GetOutputSize(); int width = (int)size.x; int height = (int)size.y; // Pick output texture dimensions based on the largest input texture. for (int i = 0; i < 4; ++i) { if (settings.SelectedModes[i] != TextureValueChannelMode.Texture || settings.GetTexture(i) == null) { continue; } mipmapCount = Math.Max(mipmapCount, GetMipmapCount(settings.GetTexture(i))); } bool doMips; if (settings.NormalMapTexture != null) { var tex = settings.NormalMapTexture; var count = GetMipmapCount(tex); mipmapCount = Math.Max(mipmapCount, count); doMips = true; } else { mipmapCount = 1; doMips = false; } if (target.width != width || target.height != height) { target.Resize(width, height); } if (!Mathf.IsPowerOfTwo(width) || !Mathf.IsPowerOfTwo(height)) { Debug.LogWarning( "Alloy: Texture resolution is not power of 2; will have issues generating correct mip maps if custom sizing is specified in generated texture platform settings."); } var readableTextures = new Texture2D[settings.TexturesGUID.Length]; for (int i = 0; i < settings.TexturesGUID.Length; ++i) { if (settings.SelectedModes[i] != TextureValueChannelMode.Texture) { continue; } var settingsTex = settings.GetTexture(i); if (settingsTex == null) { readableTextures[i] = null; } else { readableTextures[i] = AlloyTextureReader.GetReadable(settingsTex, false); } } var normal = AlloyTextureReader.GetReadable(settings.NormalMapTexture, true); try { // Use renderer to sample mipmaps. for (int mipLevel = 0; mipLevel < mipmapCount; mipLevel++) { // CPU Method - more reliable/consistent across GPUs, but slower. if (mipmapCount > 1) { EditorUtility.DisplayProgressBar("Calculating Mip Maps...", "MipLevel " + mipLevel, (float)mipLevel / mipmapCount); } else { EditorUtility.DisplayProgressBar("Calculating Packed map...", "Packing...", 1.0f); } var normalCache = new AlloyTextureColorCache(normal, target); Profiler.BeginSample("Read"); var texCache = readableTextures.Select(tex => new AlloyTextureColorCache(tex, target)).ToArray(); Profiler.EndSample(); AlloyPackerCompositor.CompositeMips(target, settings, texCache, normalCache, mipLevel); } } finally { EditorUtility.ClearProgressBar(); } foreach (var texture in readableTextures) { Object.DestroyImmediate(texture); } Object.DestroyImmediate(normal); int maxResolution = 0; settings.Width = width; settings.Height = height; settings.MaxResolution = maxResolution; EditorUtility.SetDirty(settings); // Tells Unity to save changes to the settings .asset object on disk target.Apply(!doMips, false); }