Ejemplo n.º 1
0
        void ApplyImportSettings(AlloyCustomImportObject settings, Texture2D texture, string path)
        {
            var importer       = assetImporter as TextureImporter;
            var size           = settings.GetOutputSize();
            var def            = settings.PackMode;
            var importSettings = def.ImportSettings;

            importer.textureType   = TextureImporterType.Default;
            importer.sRGBTexture   = !importSettings.IsLinear;
            importer.filterMode    = importSettings.Filter;
            importer.mipmapEnabled = true;

            // They need the ability to set this themselves, but we should cap it.
            var nextPowerOfTwo = Mathf.NextPowerOfTwo((int)Mathf.Max(size.x, size.y));

            if (importer.maxTextureSize > nextPowerOfTwo)
            {
                importer.maxTextureSize = nextPowerOfTwo;
            }

            // Allow setting to uncompressed, else use compressed. Disallows any other format!
            if (def.ImportSettings.DefaultCompressed &&
                importer.textureCompression != TextureImporterCompression.Uncompressed &&
                importer.textureCompression != TextureImporterCompression.CompressedLQ &&
                importer.textureCompression != TextureImporterCompression.CompressedHQ)
            {
                importer.textureCompression = TextureImporterCompression.Compressed;
            }
        }
Ejemplo n.º 2
0
        private void ApplyImportSettings(AlloyCustomImportObject settings, Texture2D texture, string path)
        {
            var importer = assetImporter as TextureImporter;
            var size     = settings.GetOutputSize();
            var def      = settings.PackMode;

            if (def.ImportSettings.IsLinear)
            {
                importer.textureType   = TextureImporterType.Advanced;
                importer.linearTexture = true;
            }

            importer.filterMode    = def.ImportSettings.Filter;
            importer.mipmapEnabled = true;

            // They need the ability to set this themselves, but we should cap it.
            var nextPowerOfTwo = Mathf.NextPowerOfTwo((int)Mathf.Max(size.x, size.y));

            if (importer.maxTextureSize > nextPowerOfTwo)
            {
                importer.maxTextureSize = nextPowerOfTwo;
            }

            // Allow setting to uncompressed, else use compressed. Disallows any other format!
            if (def.ImportSettings.DefaultCompressed && importer.textureFormat != TextureImporterFormat.AutomaticTruecolor)
            {
                importer.textureFormat = TextureImporterFormat.AutomaticCompressed;
            }
        }
    private void OnGUI() {
        if (Target == null) {
            Target = CreateInstance<AlloyCustomImportObject>();
            UpdateDefaults();
        }

        ScrollPosition = EditorGUILayout.BeginScrollView(ScrollPosition, false, false,
            GUILayout.MinWidth(c_editorMinWidth),
            GUILayout.MaxWidth(position.width));

        GUILayout.Space(10.0f);
        var def = Target.PackMode;

        // Pack mode tabs.
        using (new EditorGUILayout.HorizontalScope()) {
            foreach (var tabMode in GlobalDefinition.PackedMaps) {
                EditorGUI.BeginChangeCheck();
                bool toggle = GUILayout.Toggle(def == tabMode, tabMode.Title, EditorStyles.toolbarButton);

                if (EditorGUI.EndChangeCheck()) {
                    if (toggle && def != tabMode) {
                        Target.PackMode = tabMode; //Update packed map definition

                        UpdateDefaults();
                    }
                }
            }
        }
        
        string curPath;
        var suffix = Target.PackMode.Suffix;
        bool isValid = true;

        isValid = BaseGUI();
        isValid = FileEntryGUI(suffix, ".png", ref SaveName, out curPath) && isValid;

        if (GenerateButtonGUI("Generate", isValid)) {
            var path = curPath + "/" + SaveName;
            path += suffix;

            var current = Target;

            Target = Instantiate(current);

            AlloyCustomImportAction.CreatePostProcessingInformation(path + ".asset", current);
        }

        EditorGUILayout.EndScrollView();
    }
Ejemplo n.º 4
0
        /// <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);
        }
Ejemplo n.º 5
0
 public static void CreatePostProcessingInformation(string filePath, AlloyCustomImportObject settings)
 {
     settings.hideFlags = HideFlags.None;
     AssetDatabase.CreateAsset(settings, filePath);
 }
        private void ApplyImportSettings(AlloyCustomImportObject settings, Texture2D texture, string path) {
            var importer = assetImporter as TextureImporter;
            var size = settings.GetOutputSize();
            var def = settings.PackMode;

            if (def.ImportSettings.IsLinear) {
                importer.textureType = TextureImporterType.Advanced;
                importer.linearTexture = true;
            }

            importer.filterMode = def.ImportSettings.Filter;
            importer.mipmapEnabled = true;

            // They need the ability to set this themselves, but we should cap it.
            var nextPowerOfTwo = Mathf.NextPowerOfTwo((int) Mathf.Max(size.x, size.y));

            if (importer.maxTextureSize > nextPowerOfTwo) {
                importer.maxTextureSize = nextPowerOfTwo;
            }

            // Allow setting to uncompressed, else use compressed. Disallows any other format!
            if (def.ImportSettings.DefaultCompressed && importer.textureFormat != TextureImporterFormat.AutomaticTruecolor) {
                importer.textureFormat = TextureImporterFormat.AutomaticCompressed;
            }
        }
        /// <summary>
        /// Generates the packed material map for an object
        /// </summary>
        public static void GeneratePackedMaterialMap(AlloyCustomImportObject settings, Texture2D source, string filePath) {
            int mipmapCount = 1;
            bool isEditorInLinearSpace = PlayerSettings.colorSpace == ColorSpace.Linear;

            Shader.SetGlobalFloat("_EditorIsLinear", isEditorInLinearSpace ? 1.0f : 0.0f);

            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 (source.width != width || source.height != height) {
                source.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];
            var linear = new bool[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;
                    linear[i] = false;
                } else {
                    var texImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(settingsTex)) as TextureImporter;

                    if (texImporter == null) {
                        Debug.LogError("Couldn't find packed map texture in asset database!");
                        return;
                    }

                    readableTextures[i] = AlloyTextureReader.GetReadable(settingsTex, false);
                    linear[i] = isEditorInLinearSpace && !texImporter.linearTexture;
                }
            }

            var normal = AlloyTextureReader.GetReadable(settings.NormalMapTexture, true);

            // Use renderer to sample mipmaps.
            for (int mipLevel = 0; mipLevel < mipmapCount; mipLevel++) {
                // CPU Method - more reliable/consistent across GPUs, but slower.
                EditorUtility.DisplayProgressBar("Calculating Mip Maps...", "MipLevel " + mipLevel, (float) mipLevel / mipmapCount);

                try {
                    AlloyPackerCompositor.CompositeMips(source, settings, readableTextures, linear, normal, 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

            source.Apply(!doMips, false);
        }
 public static void CreatePostProcessingInformation(string filePath, AlloyCustomImportObject settings) {
     settings.hideFlags = HideFlags.None;
     AssetDatabase.CreateAsset(settings, filePath);
 }
        public static void CompositeMips(Texture2D target, AlloyCustomImportObject source, 
            Texture2D[] maps,
            bool[] linear,
            Texture2D normalMap, 
            int mipLevel) {
            // Basically a 1:1 port of the original shader
            // The only point of major difference is the filtering method used; which is a fraction simpler.

            // This was disabled, since it appears GetPixels results don't appear to be affected by Unity's messing with Linear inputs; the same way they do at runtime. Re-enable if you like.

            int w = Mathf.Max(1, target.width >> mipLevel);
            int h = Mathf.Max(1, target.height >> mipLevel);

            var colors = new Color[w * h];

            float offX = 0.5f / w; // Half a pixel
            float offY = 0.5f / h;

            float rangeX = (1.0f / (mipLevel + 1)) / w;
            float rangeY = (1.0f / (mipLevel + 1)) / h;


            foreach (var channel in source.PackMode.Channels) {
                var inIndices = channel.InputIndices.ToArray();
                var outIndices = channel.OutputIndices.ToArray();

                for (int x = 0; x < w; x++) {
                    for (int y = 0; y < h; y++) {
                        float u = (float)x / w + offX;
                        float v = (float)y / h + offY;

                        Color col = colors[y * w + x];

                        float variance = 0.0f, avgNormalLength = 0.0f;


                        if (channel.UseNormals && normalMap != null) {
                            Vector4 normal = GetChannels(normalMap, u, v, mipLevel, w, h, rangeX, rangeY);
                            normal.x = (normal.x * 2.0f) - 1.0f;
                            normal.y = (normal.y * 2.0f) - 1.0f;
                            normal.z = (normal.z * 2.0f) - 1.0f;

                            avgNormalLength = ((Vector3)normal).magnitude;
                            float avgNormLen2 = avgNormalLength * avgNormalLength;
                            float kappa = (3.0f * avgNormalLength - avgNormalLength * avgNormLen2) / (1.0f - avgNormLen2);
                            variance = Mathf.Clamp01((1.0f / (2.0f * kappa)) - source.VarianceBias);
                        }

                        for (int i = 0; i < outIndices.Length; ++i) {
                            int storeIndex = outIndices[i];

                            var tex = maps[storeIndex];
                            var channelVal = source.ChannelValues[storeIndex];

                            float input = 0.0f;

                            if (channel.OutputVariance) {
                                input = variance;
                            } else if (inIndices.Length > 0) {
                                int read = inIndices[Mathf.Min(i, inIndices.Length - 1)];
                                input = GetChannel(tex, channelVal, linear[storeIndex], u, v, mipLevel, rangeX, rangeY, read);
                            } 

                            if (channel.RoughnessCorrect) {
                                // Specular AA for Beckmann roughness.
                                // cf http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf pg92
                                if (avgNormalLength < 1.0f) {
                                    float a = input * input;
                                    a = Mathf.Sqrt(Mathf.Clamp01(a * a + variance));
                                    input = Mathf.Sqrt(a);
                                }
                            }

                            if (source.DoInvert[storeIndex]) {
                                input = 1.0f - input;
                            }

                            col[storeIndex] = input;
                        }

                        colors[y * w + x] = col;
                    }
                }
            }

            target.SetPixels(colors, mipLevel);
        }
Ejemplo n.º 10
0
        public static void CompositeMips(Texture2D target, AlloyCustomImportObject source,
                                         AlloyTextureColorCache[] mapCache, AlloyTextureColorCache normalCache, int mipLevel)
        {
            // Basically a 1:1 port of the original shader
            // The only point of major difference is the filtering method used; which is a fraction simpler.

            // This was disabled, since it appears GetPixels results don't appear to be affected by Unity's messing with Linear inputs; the same way they do at runtime. Re-enable if you like.

            int w = Mathf.Max(2, target.width >> mipLevel);
            int h = Mathf.Max(2, target.height >> mipLevel);

            var colors = new Color[w * h];


            float rangeX = (1.0f / (mipLevel + 1)) / target.width;
            float rangeY = (1.0f / (mipLevel + 1)) / target.height;

            UnityEngine.Profiling.Profiler.BeginSample("Composite mips");
            for (int channelIndex = 0; channelIndex < source.PackMode.Channels.Count; channelIndex++)
            {
                var  channel    = source.PackMode.Channels[channelIndex];
                var  inIndices  = channel.InputIndices.ToArray();
                var  outIndices = channel.OutputIndices.ToArray();
                bool hasInputs  = inIndices.Length > 0;

                for (int i = 0; i < outIndices.Length; ++i)
                {
                    int storeIndex = outIndices[i];
                    var tex        = mapCache[storeIndex];
                    var channelVal = source.ChannelValues[storeIndex];

                    if (hasInputs)
                    {
                        int readIndex = inIndices[Mathf.Min(i, inIndices.Length - 1)];

                        tex.SetActiveChannel(readIndex);
                    }

                    bool doInvert = source.DoInvert[storeIndex];
                    bool doNormal = channel.UseNormals && !normalCache.EmptyTexture;
                    bool doNative = hasInputs && tex.NativeSize && mipLevel == 0;

                    UnityEngine.Profiling.Profiler.BeginSample("Blit");
                    for (int x = 0; x < w; ++x)
                    {
                        for (int y = 0; y < h; ++y)
                        {
                            var pixelIndex = x + y * w;
                            var input      = 0.0f;

                            if (!hasInputs || tex.EmptyTexture)
                            {
                                input = channelVal;
                            }
                            else if (doNative)
                            {
                                input = tex.ActiveChannel[pixelIndex];
                            }
                            else
                            {
                                input = tex.GetChannelBilinear((float)x / (w - 1), (float)y / (h - 1), mipLevel, rangeX, rangeY);
                            }

                            if (doInvert)
                            {
                                input = 1.0f - input;
                            }

                            if (doNormal)
                            {
                                Vector3 normal;

                                if (normalCache.NativeSize && mipLevel == 0)
                                {
                                    normal = (Vector4)normalCache.Values[pixelIndex];
                                }
                                else
                                {
                                    normal = normalCache.GetPixelNormal((float)x / (w - 1), (float)y / (h - 1), mipLevel, rangeX,
                                                                        rangeY);
                                }

                                normal.x = (normal.x * 2.0f) - 1.0f;
                                normal.y = (normal.y * 2.0f) - 1.0f;
                                normal.z = (normal.z * 2.0f) - 1.0f;

                                // Specular AA for Beckmann roughness.
                                // cf http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf pg92
                                var variance        = 0.0f;
                                var avgNormalLength = normal.magnitude;
                                var applyAA         = avgNormalLength < 1.0f;

                                if (applyAA)
                                {
                                    float avgNormLen2 = avgNormalLength * avgNormalLength;
                                    float kappa       = (3.0f * avgNormalLength - avgNormalLength * avgNormLen2) / (1.0f - avgNormLen2);

                                    variance = Mathf.Clamp01(1.0f / (2.0f * kappa));// - source.VarianceBias);
                                }

                                if (channel.OutputVariance)
                                {
                                    input = variance;
                                }
                                else if (channel.RoughnessCorrect && applyAA)
                                {
                                    float a = input * input;
                                    a     = Mathf.Sqrt(Mathf.Clamp01(a * a + variance));
                                    input = Mathf.Sqrt(a);
                                }
                            }

                            switch (storeIndex)
                            {
                            case 0: colors[pixelIndex].r = input; break;

                            case 1: colors[pixelIndex].g = input; break;

                            case 2: colors[pixelIndex].b = input; break;

                            case 3: colors[pixelIndex].a = input; break;
                            }
                        }
                    }

                    UnityEngine.Profiling.Profiler.EndSample();
                }
            }

            UnityEngine.Profiling.Profiler.BeginSample("Set pixels");
            target.SetPixels(colors, mipLevel);
            UnityEngine.Profiling.Profiler.EndSample();

            UnityEngine.Profiling.Profiler.EndSample();
        }
Ejemplo n.º 11
0
        /// <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);
        }