Ejemplo n.º 1
0
        public void InitCamera()
        {
            this.needsReinitialisation = false;
            if (this.ActiveGlow)
            {
                this.DestroyCamera();
            }
            this.glowObj.SetActive(true);
            IBlur blur = null;

            this.useRt = false;
            BlurMode blurMode = this.blurMode;

            if (blurMode != BlurMode.Default)
            {
                if (blurMode != BlurMode.Advanced)
                {
                    if (blurMode != BlurMode.HighQuality)
                    {
                        if (blurMode == BlurMode.UnityBlur)
                        {
                            blur = new UnityBlur();
                        }
                    }
                    else
                    {
                        blur = new HqBlur();
                    }
                }
                else
                {
                    blur = new AdvancedBlur();
                }
            }
            else
            {
                blur = new DefaultBlur();
            }
            this.glowCam.enabled = false;
            if (this._reuseDepth && QualitySettings.antiAliasing == 0)
            {
                this.reuseDepthDisabled = false;
                this.ActiveGlow         = this.glowCam.gameObject.AddComponent <GlowCameraReuse>();
            }
            else
            {
                this.reuseDepthDisabled = true;
                this.useRt      = true;
                this.ActiveGlow = this.glowCam.gameObject.AddComponent <GlowCameraRerenderOnly>();
            }
            this.ActiveGlow.glow11        = this;
            this.ActiveGlow.cullingMask   = this.cullingMask;
            this.ActiveGlow.highPrecision = this._highPrecsionActive;
            this.ActiveGlow.parentCamera  = base.GetComponent <Camera>();
            this.ActiveGlow.blur          = blur;
            this.ActiveGlow.settings      = this.settings;
            this.ActiveGlow.Init();
        }
Ejemplo n.º 2
0
 public static string GetVariantName(Shader shader, BlurMode blur)
 {
     return
         (#if UIEFFECT_SEPARATE
          "[Separated] " + Path.GetFileName(shader.name)
             #else
          Path.GetFileName(shader.name)
             #endif
          + (0 < blur ? "-" + blur : ""));
 }
Ejemplo n.º 3
0
    public static Material GetMaterial(Shader shader, BlurMode blur)
    {
        string variantName = GetVariantName(shader, blur);

        return(AssetDatabase.FindAssets("t:Material " + Path.GetFileName(shader.name))
               .Select(x => AssetDatabase.GUIDToAssetPath(x))
               .SelectMany(x => AssetDatabase.LoadAllAssetsAtPath(x))
               .OfType <Material>()
               .FirstOrDefault(x => x.name == variantName));
    }
Ejemplo n.º 4
0
        private void btnMode_Click(object sender, EventArgs e)
        {
            layoutParams.SuspendLayout();
            if (sender == btnModeNormal)
            {
                blurMode = BlurMode.Normal;

                grpGaussianParams.Enabled = false;
                grpBoxParams.Enabled      = false;
                grpGdiParams.Enabled      = false;

                grpGaussianParams.Visible = false;
                grpBoxParams.Visible      = false;
                grpGdiParams.Visible      = false;
            }
            else if (sender == btnModeGaussian)
            {
                blurMode = BlurMode.Gaussian;

                grpGaussianParams.Enabled = true;
                grpBoxParams.Enabled      = false;
                grpGdiParams.Enabled      = false;

                grpGaussianParams.Visible = true;
                grpBoxParams.Visible      = false;
                grpGdiParams.Visible      = false;
            }
            else if (sender == btnModeBox)
            {
                blurMode = BlurMode.Box;

                grpGaussianParams.Enabled = false;
                grpBoxParams.Enabled      = true;
                grpGdiParams.Enabled      = false;

                grpGaussianParams.Visible = false;
                grpBoxParams.Visible      = true;
                grpGdiParams.Visible      = false;
            }
            else if (sender == btnModeGdi)
            {
                blurMode = BlurMode.GDI;
                grpGaussianParams.Enabled = false;
                grpBoxParams.Enabled      = false;
                grpGdiParams.Enabled      = true;

                grpGaussianParams.Visible = false;
                grpBoxParams.Visible      = false;
                grpGdiParams.Visible      = true;
            }
            layoutParams.ResumeLayout();
            imgPreview.Image = addin.Apply(thumb);
        }
Ejemplo n.º 5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        public override Image Apply(Image image)
        {
            GetParams(fm);

            if (!(image is Image))
            {
                return(image);
            }

            Bitmap dst = AddinUtils.CloneImage(image) as Bitmap;

            BlurMode blurMode          = (BlurMode)Params["BlurMode"].Value;
            double   gaussianSigma     = (double)Params["GaussianSigma"].Value;
            int      gaussianSize      = (int)Params["GaussianSize"].Value;
            int      gaussianThreshold = (int)Params["GaussianThreshold"].Value;
            int      boxSize           = (int)Params["BoxSize"].Value;
            float    gdiRatio          = (float)Params["GdiRatio"].Value;

            Accord.Imaging.Filters.IFilter filter = null;
            switch (blurMode)
            {
            case BlurMode.Normal:
                filter = new Accord.Imaging.Filters.Blur();
                if (dst is Image)
                {
                    dst = (filter as Accord.Imaging.Filters.Blur).Apply(dst);
                }
                break;

            case BlurMode.Gaussian:
                filter = new Accord.Imaging.Filters.GaussianBlur();
                (filter as Accord.Imaging.Filters.GaussianBlur).Sigma     = gaussianSigma;
                (filter as Accord.Imaging.Filters.GaussianBlur).Size      = gaussianSize;
                (filter as Accord.Imaging.Filters.GaussianBlur).Threshold = gaussianThreshold;
                dst = filter.Apply(dst);
                break;

            case BlurMode.Box:
                filter = new Accord.Imaging.Filters.FastBoxBlur((byte)boxSize, (byte)boxSize);
                dst    = AddinUtils.ProcessImage(filter, dst, false);
                break;

            case BlurMode.GDI:
                var effect = new BlurEffect(gdiRatio, true);
                dst.ApplyEffect(effect, new Rectangle(0, 0, dst.Width, dst.Height));
                break;
            }
            AddinUtils.CloneExif(image, dst);
            return(dst);
        }
Ejemplo n.º 6
0
    public static Material GetOrGenerateMaterialVariant(Shader shader, BlurMode blur)
    {
        if (!shader)
        {
            return(null);
        }

        Material mat = GetMaterial(shader, blur);

        if (!mat)
        {
            Debug.Log("Generate material : " + GetVariantName(shader, blur));
            mat = new Material(shader);

            if (0 < blur)
            {
                mat.EnableKeyword("UI_BLUR_" + blur.ToString().ToUpper());
            }

            mat.name       = GetVariantName(shader, blur);
            mat.hideFlags |= HideFlags.NotEditable;

                #if UIEFFECT_SEPARATE
            bool   isMainAsset  = true;
            string dir          = Path.GetDirectoryName(GetDefaultMaterialPath(shader));
            string materialPath = Path.Combine(Path.Combine(dir, "Separated"), mat.name + ".mat");
                #else
            bool   isMainAsset  = (0 == blur);
            string materialPath = GetDefaultMaterialPath(shader);
                #endif
            if (isMainAsset)
            {
                Directory.CreateDirectory(Path.GetDirectoryName(materialPath));
                AssetDatabase.CreateAsset(mat, materialPath);
                AssetDatabase.SaveAssets();
            }
            else
            {
                mat.hideFlags |= HideFlags.HideInHierarchy;
                AssetDatabase.AddObjectToAsset(mat, materialPath);
            }
        }
        return(mat);
    }
Ejemplo n.º 7
0
        /// <summary>
        /// Mark the UIEffect as dirty.
        /// </summary>
        /// <param name="isMaterialDirty">If set to true material dirty.</param>
        void SetDirty(bool isMaterialDirty = false)
        {
            //
            if (!mainEffect)
            {
                mainEffect = GetComponent <UIEffect>();
            }

            // Only main effect update material.
            if (mainEffect != this)
            {
                m_ToneMode  = mainEffect.m_ToneMode;
                m_ColorMode = mainEffect.m_ColorMode;
                m_BlurMode  = mainEffect.m_BlurMode;
                return;
            }

            // Update material if needed.
            if (isMaterialDirty && mainEffect == this)
            {
                const int TONE_SHIFT     = 0;
                const int TONE_GRAYSCALE = (int)ToneMode.Grayscale;
                const int TONE_SEPIA     = (int)ToneMode.Sepia;
                const int TONE_NEGA      = (int)ToneMode.Nega;

                const int COLOR_SHIFT = 2;
                const int COLOR_SET   = (int)ColorMode.Set;
                const int COLOR_ADD   = (int)ColorMode.Add;
                const int COLOR_SUB   = (int)ColorMode.Sub;

                const int BLUR_SHIFT  = 4;
                const int BLUR_FAST   = (int)BlurMode.Fast;
                const int BLUR_DETAIL = (int)BlurMode.Detail;

                // Calculate shader keyword identifier from effect modes.
                int identifier = ((int)m_ToneMode << TONE_SHIFT) | ((int)m_ColorMode << COLOR_SHIFT) | ((int)m_BlurMode << BLUR_SHIFT);

                // When all effect modes are disable(None), graphic uses default material.
                if (identifier == 0)
                {
                    graphic.material = null;
                    graphic.SetVerticesDirty();
                    return;
                }

                // Generate and cache new material by given identifier.
                if (!s_SharedMaterials[identifier])
                {
                    if (!s_SharedMaterials[0])
                    {
                        s_SharedMaterials[0] = new Material(shader);
                    }
                    Material mat = new Material(s_SharedMaterials[0]);

                    // Bits for tone effect.
                    int toneBits = identifier >> TONE_SHIFT;
                    mat.EnableKeyword(
                        TONE_NEGA == (toneBits & TONE_NEGA) ? "UI_TONE_NEGA"
                                                : TONE_SEPIA == (toneBits & TONE_SEPIA) ? "UI_TONE_SEPIA"
                                                : TONE_GRAYSCALE == (toneBits & TONE_GRAYSCALE) ? "UI_TONE_GRAYSCALE"
                                                : "UI_TONE_OFF"
                        );

                    // Bits for color effect.
                    int colorBits = identifier >> COLOR_SHIFT;
                    mat.EnableKeyword(
                        COLOR_SUB == (colorBits & COLOR_SUB) ? "UI_COLOR_SUB"
                                                : COLOR_ADD == (colorBits & COLOR_ADD) ? "UI_COLOR_ADD"
                                                : COLOR_SET == (colorBits & COLOR_SET) ? "UI_COLOR_SET"
                                                : "UI_COLOR_OFF"
                        );

                    // Bits for blur effect.
                    int blurBits = identifier >> BLUR_SHIFT;
                    mat.EnableKeyword(
                        BLUR_DETAIL == (blurBits & BLUR_DETAIL) ? "UI_BLUR_DETAIL"
                                                : BLUR_FAST == (blurBits & BLUR_FAST) ? "UI_BLUR_FAST"
                                                : "UI_BLUR_OFF"
                        );

                    mat.name += identifier.ToString();
                    s_SharedMaterials[identifier] = mat;
                }

                graphic.material = s_SharedMaterials[identifier];
            }
            graphic.SetVerticesDirty();
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Implement this function to make a custom inspector.
        /// </summary>
        public override void OnInspectorGUI()
        {
            foreach (var d in targets.Cast <UIEffect> ())
            {
                var mat = d.material;
                if (d.isTMPro && mat)
                {
                    var        so    = new SerializedObject(d);
                    EffectMode eMode = (EffectMode)GetEnum <EffectMode> (mat);
                    ColorMode  cMode = (ColorMode)GetEnum <ColorMode> (mat);
                    BlurMode   bMode = (BlurMode)GetEnum <BlurMode> (mat);
                    bool       aBlur = mat.IsKeywordEnabled("EX");
                    if (d.effectMode != eMode || d.colorMode != cMode || d.blurMode != bMode || so.FindProperty("m_AdvancedBlur").boolValue != aBlur)
                    {
                        so.FindProperty("m_EffectMode").intValue    = (int)eMode;
                        so.FindProperty("m_ColorMode").intValue     = (int)cMode;
                        so.FindProperty("m_BlurMode").intValue      = (int)bMode;
                        so.FindProperty("m_AdvancedBlur").boolValue = aBlur;
                        so.ApplyModifiedProperties();
                    }
                }
            }


            serializedObject.Update();
            bool isAnyTMPro = targets.Cast <UIEffect>().Any(x => x.isTMPro);
            var  c          = target as UIEffect;

            //================
            // Effect material.
            //================
            var spMaterial = serializedObject.FindProperty("m_EffectMaterial");

            EditorGUI.BeginDisabledGroup(true);
            EditorGUILayout.PropertyField(spMaterial);
            EditorGUI.EndDisabledGroup();

            //================
            // Effect setting.
            //================
            var spToneMode = serializedObject.FindProperty("m_EffectMode");

            using (new EditorGUI.DisabledGroupScope(isAnyTMPro))
                EditorGUILayout.PropertyField(spToneMode);

            // When tone is enable, show parameters.
            if (spToneMode.intValue != (int)EffectMode.None)
            {
                EditorGUI.indentLevel++;
                EditorGUILayout.PropertyField(serializedObject.FindProperty("m_EffectFactor"));
                EditorGUI.indentLevel--;
            }

            //================
            // Color setting.
            //================
            var spColorMode = serializedObject.FindProperty("m_ColorMode");

            using (new EditorGUI.DisabledGroupScope(isAnyTMPro))
                EditorGUILayout.PropertyField(spColorMode);

            // When color is enable, show parameters.
            //if (spColorMode.intValue != (int)ColorMode.Multiply)
            {
                EditorGUI.indentLevel++;

                SerializedProperty spColor = serializedObject.FindProperty("m_Color");
                if (spColor == null && serializedObject.targetObject is UIEffect)
                {
                    spColor = new SerializedObject(serializedObject.targetObjects.Select(x => (x as UIEffect).targetGraphic).ToArray()).FindProperty(!isAnyTMPro ? "m_Color" : "m_fontColor");
                }

                EditorGUI.BeginChangeCheck();
                EditorGUI.showMixedValue = spColor.hasMultipleDifferentValues;
                                #if UNITY_2018_1_OR_NEWER
                spColor.colorValue = EditorGUILayout.ColorField(contentEffectColor, spColor.colorValue, true, false, false);
                                #else
                spColor.colorValue = EditorGUILayout.ColorField(contentEffectColor, spColor.colorValue, true, false, false, null);
                                #endif
                if (EditorGUI.EndChangeCheck())
                {
                    spColor.serializedObject.ApplyModifiedProperties();
                }

                EditorGUILayout.PropertyField(serializedObject.FindProperty("m_ColorFactor"));
                EditorGUI.indentLevel--;
            }

            //================
            // Blur setting.
            //================
            var spBlurMode = serializedObject.FindProperty("m_BlurMode");
            using (new EditorGUI.DisabledGroupScope(isAnyTMPro))
                EditorGUILayout.PropertyField(spBlurMode);

            // When blur is enable, show parameters.
            if (spBlurMode.intValue != (int)BlurMode.None)
            {
                EditorGUI.indentLevel++;
                EditorGUILayout.PropertyField(serializedObject.FindProperty("m_BlurFactor"));

                var spAdvancedBlur = serializedObject.FindProperty("m_AdvancedBlur");
                using (new EditorGUI.DisabledGroupScope(isAnyTMPro))
                    EditorGUILayout.PropertyField(spAdvancedBlur);
                EditorGUI.indentLevel--;
            }

            serializedObject.ApplyModifiedProperties();

            c.ShowTMProWarning(_shader, _mobileShader, _spriteShader, mat => {});
            ShowCanvasChannelsWarning();

            ShowMaterialEditors(c.materials, 1, c.materials.Length - 1);

            serializedObject.ApplyModifiedProperties();
        }
Ejemplo n.º 9
0
        public static IImageProcessingContext <TPixel> Blur <TPixel>(this IImageProcessingContext <TPixel> source, Rectangle sourceRectangle, BlurMode mode, float radius) where TPixel : struct, IPixel <TPixel>
        {
            if (mode == BlurMode.Box)
            {
                return(source.BoxBlur((int)radius, sourceRectangle));
            }
            if (mode == BlurMode.Gaussian)
            {
                return(source.GaussianBlur(radius, sourceRectangle));
            }

            throw new NotImplementedException();
        }
Ejemplo n.º 10
0
        public override void OnInspectorGUI()
        {
            Glow11 glow = (Glow11)base.target;

            this.serObj.Update();
            EditorGUILayout.PropertyField(this.cullingMask, new GUIContent("Effected Layer"));
            if (!PlayerSettings.use32BitDisplayBuffer)
            {
                EditorGUILayout.HelpBox("It is recommended you use a 32-bit display buffer (can be set in the player settings).", MessageType.Warning);
            }
            bool flag  = false;
            bool flag2 = EditorGUILayout.Toggle("High Precision", glow.highPrecision, new GUILayoutOption[0]);

            if (glow.highPrecision != flag2)
            {
                Undo.RecordObject(glow, "High Precision");
                glow.highPrecision = flag2;
                EditorUtility.SetDirty(glow);
            }
            if (glow.highPrecision && !glow.highPrecisionActive)
            {
                EditorGUILayout.HelpBox("Your graphics card doesn't support High Precision.", MessageType.Warning);
            }
            if (QualitySettings.antiAliasing != 0)
            {
                GUI.enabled = false;
            }
            bool flag3 = EditorGUILayout.Toggle("Reuse Depth Buffer", glow.reuseDepth, new GUILayoutOption[0]);

            GUI.enabled = true;
            if (flag3 != glow.reuseDepth)
            {
                Undo.RecordObject(glow, "Reuse Depthbuffer");
                glow.reuseDepth = flag3;
                EditorUtility.SetDirty(glow);
                flag = true;
            }
            if (QualitySettings.antiAliasing != 0)
            {
                EditorGUILayout.HelpBox("Reuse Depth Buffer is only available when antialiasing is disabled.", MessageType.Info);
            }
            if (flag3 && QualitySettings.antiAliasing == 0)
            {
                GUI.enabled = false;
            }
            Resolution resolution = (Resolution)EditorGUILayout.EnumPopup("Rerender Resolution", glow.rerenderResolution, new GUILayoutOption[0]);

            if (resolution != glow.rerenderResolution)
            {
                Undo.RecordObject(glow, "Rerender Resolution");
                glow.rerenderResolution = resolution;
                EditorUtility.SetDirty(glow);
                flag = true;
            }
            GUI.enabled = true;
            EditorGUILayout.Space();
            BlurMode blurMode = (BlurMode)EditorGUILayout.IntPopup("Blur Mode", (int)glow.blurMode, this.blurModeOptions, this.blurModeValues, new GUILayoutOption[0]);

            EditorGUI.indentLevel = EditorGUI.indentLevel + 1;
            if (blurMode != glow.blurMode)
            {
                Undo.RecordObject(glow, "Blur Mode");
                glow.blurMode = blurMode;
                EditorUtility.SetDirty(glow);
                flag = true;
            }
            if (glow.blurMode == BlurMode.Advanced)
            {
                this.falloff.animationCurveValue = EditorGUILayout.CurveField("Falloff", this.falloff.animationCurveValue, Color.green, new Rect(0f, 0f, 1f, 1f), new GUILayoutOption[]
                {
                    GUILayout.Height(100f)
                });
                EditorGUILayout.PropertyField(this.normalize, new GUILayoutOption[0]);
                GUILayout.BeginHorizontal(new GUILayoutOption[0]);
                this.falloffScale.floatValue = EditorGUILayout.Slider("Scale", this.falloffScale.floatValue, 0.1f, 2f, new GUILayoutOption[0]);
                if (GUILayout.Button("Reset", new GUILayoutOption[0]))
                {
                    GUI.FocusControl("");
                    this.falloffScale.floatValue = 1f;
                }
                GUILayout.EndHorizontal();
                GUILayout.BeginHorizontal(new GUILayoutOption[0]);
                this.radius.intValue = EditorGUILayout.IntSlider("Radius", this.radius.intValue, 1, 30, new GUILayoutOption[0]);
                if (GUILayout.Button("Reset", new GUILayoutOption[0]))
                {
                    GUI.FocusControl("");
                    this.radius.intValue = 3;
                }
                GUILayout.EndHorizontal();
                if (this.radius.intValue <= 12)
                {
                    EditorGUILayout.HelpBox("A radius greater then 12 requires Shader Model 3.", MessageType.Info);
                }
                else
                {
                    EditorGUILayout.HelpBox("You've set a radius greater then 12, with this setting shader model 3 is required.", MessageType.Warning);
                }
            }
            if (glow.blurMode == BlurMode.HighQuality || glow.blurMode == BlurMode.UnityBlur || glow.blurMode == BlurMode.Advanced)
            {
                GUILayout.BeginHorizontal(new GUILayoutOption[0]);
                this.iterations.intValue = EditorGUILayout.IntSlider("Iterations", this.iterations.intValue, 1, 20, new GUILayoutOption[0]);
                if (GUILayout.Button("Reset", new GUILayoutOption[0]))
                {
                    GUI.FocusControl("");
                    this.iterations.intValue = 3;
                }
                GUILayout.EndHorizontal();
            }
            if (glow.blurMode == BlurMode.UnityBlur)
            {
                GUILayout.BeginHorizontal(new GUILayoutOption[0]);
                this.blurSpread.floatValue = EditorGUILayout.Slider("Blur Spread", this.blurSpread.floatValue, 0.01f, 10f, new GUILayoutOption[0]);
                if (GUILayout.Button("Reset", new GUILayoutOption[0]))
                {
                    GUI.FocusControl("");
                    this.blurSpread.floatValue = 0.6f;
                }
                GUILayout.EndHorizontal();
            }
            if (glow.blurMode == BlurMode.Default || glow.blurMode == BlurMode.HighQuality || glow.blurMode == BlurMode.Advanced)
            {
                EditorGUILayout.PropertyField(this.baseResolution, new GUILayoutOption[0]);
            }
            if (glow.blurMode == BlurMode.Default)
            {
                GUILayout.BeginHorizontal(new GUILayoutOption[0]);
                this.downsampleSteps.intValue = EditorGUILayout.IntSlider("Downsample Steps", this.downsampleSteps.intValue, 0, 10, new GUILayoutOption[0]);
                if (GUILayout.Button("Reset", new GUILayoutOption[0]))
                {
                    GUI.FocusControl("");
                    this.downsampleSteps.intValue = 2;
                }
                GUILayout.EndHorizontal();
                GUI.enabled = this.downsampleSteps.intValue >= 1;
                EditorGUILayout.PropertyField(this.downsampleResolution, new GUILayoutOption[0]);
                EditorGUILayout.PropertyField(this.downsampleBlendMode, new GUILayoutOption[0]);
                GUI.enabled = true;
            }
            if (glow.blurMode != BlurMode.Advanced)
            {
                GUILayout.BeginHorizontal(new GUILayoutOption[0]);
                this.innerStrength.floatValue = EditorGUILayout.Slider("Inner Strength", this.innerStrength.floatValue, 0.01f, 10f, new GUILayoutOption[0]);
                if (GUILayout.Button("Reset", new GUILayoutOption[0]))
                {
                    GUI.FocusControl("");
                    this.innerStrength.floatValue = 1f;
                }
                GUILayout.EndHorizontal();
            }
            if (glow.blurMode == BlurMode.Default)
            {
                GUILayout.BeginHorizontal(new GUILayoutOption[0]);
                this.outerStrength.floatValue = EditorGUILayout.Slider("Outer Strength", this.outerStrength.floatValue, 0.01f, 10f, new GUILayoutOption[0]);
                if (GUILayout.Button("Reset", new GUILayoutOption[0]))
                {
                    GUI.FocusControl("");
                    this.outerStrength.floatValue = 1f;
                }
                GUILayout.EndHorizontal();
            }
            GUILayout.BeginHorizontal(new GUILayoutOption[0]);
            this.boostStrength.floatValue = EditorGUILayout.Slider("Boost Strength", this.boostStrength.floatValue, 0.01f, 10f, new GUILayoutOption[0]);
            if (GUILayout.Button("Reset", new GUILayoutOption[0]))
            {
                GUI.FocusControl("");
                this.boostStrength.floatValue = 1f;
            }
            GUILayout.EndHorizontal();
            EditorGUI.indentLevel = EditorGUI.indentLevel - 1;
            EditorGUILayout.Space();
            EditorGUILayout.PropertyField(this.blendMode, new GUILayoutOption[0]);
            if ((this.serObj.ApplyModifiedProperties() || flag) && EditorApplication.isPaused)
            {
                ((Glow11)base.target).InitCamera();
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Get shared material for identifier.
        /// </summary>
        /// <param name="isMaterialDirty">If set to true material dirty.</param>
        public static Material GetSharedMaterial(Shader shader, ToneMode toneMode, ColorMode colorMode, BlurMode blurMode, bool nullDefault = true)
        {
            // Update material if needed.
            const int TONE_SHIFT     = 0;
            const int TONE_GRAYSCALE = (int)ToneMode.Grayscale;
            const int TONE_SEPIA     = (int)ToneMode.Sepia;
            const int TONE_NEGA      = (int)ToneMode.Nega;
            const int TONE_PIXEL     = (int)ToneMode.Pixel;
            const int TONE_MONO      = (int)ToneMode.Mono;
            const int TONE_CUTOFF    = (int)ToneMode.Cutoff;

            const int COLOR_SHIFT = 3;
            const int COLOR_SET   = (int)ColorMode.Set;
            const int COLOR_ADD   = (int)ColorMode.Add;
            const int COLOR_SUB   = (int)ColorMode.Sub;

            const int BLUR_SHIFT  = 5;
            const int BLUR_FAST   = (int)BlurMode.Fast;
            const int BLUR_MEDIUM = (int)BlurMode.Medium;
            const int BLUR_DETAIL = (int)BlurMode.Detail;

            // Calculate shader keyword identifier from effect modes.
            int identifier = ((int)toneMode << TONE_SHIFT)
                             | ((int)colorMode << COLOR_SHIFT)
                             | ((int)blurMode << BLUR_SHIFT);

            // When all effect modes are disable(None), graphic uses default material.
            if (nullDefault && identifier == 0)
            {
                return(null);
            }

            Material[] materials;

            if (!s_SharedMaterials.TryGetValue(shader, out materials))
            {
                materials = new Material[128];
                s_SharedMaterials.Add(shader, materials);
            }

            // Generate and cache new material by given identifier.
            if (!materials[identifier])
            {
                if (!materials[0])
                {
                    materials[0]       = new Material(shader);
                    materials[0].name += identifier.ToString();
                }
                if (identifier == 0)
                {
                    return(materials[0]);
                }

                Material mat = new Material(materials[0]);

                // Bits for tone effect.
                int toneBits = identifier >> TONE_SHIFT;
                mat.EnableKeyword(
                    TONE_CUTOFF == (toneBits & TONE_CUTOFF) ? "UI_TONE_CUTOFF"
                                        : TONE_MONO == (toneBits & TONE_MONO) ? "UI_TONE_MONO"
                                        : TONE_PIXEL == (toneBits & TONE_PIXEL) ? "UI_TONE_PIXEL"
                                        : TONE_NEGA == (toneBits & TONE_NEGA) ? "UI_TONE_NEGA"
                                        : TONE_SEPIA == (toneBits & TONE_SEPIA) ? "UI_TONE_SEPIA"
                                        : TONE_GRAYSCALE == (toneBits & TONE_GRAYSCALE) ? "UI_TONE_GRAYSCALE"
                                        : "UI_TONE_OFF"
                    );

                // Bits for color effect.
                int colorBits = identifier >> COLOR_SHIFT;
                mat.EnableKeyword(
                    COLOR_SUB == (colorBits & COLOR_SUB) ? "UI_COLOR_SUB"
                                        : COLOR_ADD == (colorBits & COLOR_ADD) ? "UI_COLOR_ADD"
                                        : COLOR_SET == (colorBits & COLOR_SET) ? "UI_COLOR_SET"
                                        : "UI_COLOR_OFF"
                    );

                // Bits for blur effect.
                int blurBits = identifier >> BLUR_SHIFT;
                mat.EnableKeyword(
                    BLUR_DETAIL == (blurBits & BLUR_DETAIL) ? "UI_BLUR_DETAIL"
                                        : BLUR_MEDIUM == (blurBits & BLUR_MEDIUM) ? "UI_BLUR_MEDIUM"
                                        : BLUR_FAST == (blurBits & BLUR_FAST) ? "UI_BLUR_FAST"
                                        : "UI_BLUR_OFF"
                    );

                mat.name += identifier.ToString();
                materials[identifier] = mat;
            }
            return(materials[identifier]);
        }