protected virtual void SetMaterialAutoPropertiesAndKeywords(Material mat)
        {
            ShaderGUIUtils.SetKeyword(mat, "_USEMAINTEX_ON", mat.GetTexture("_MainTex"));
            ShaderGUIUtils.SetKeyword(mat, "_USEOCCLUSIONMAP_ON", mat.GetTexture("_OcclusionMap"));

            bool usesBumpMap     = mat.GetTexture("_BumpMap");
            bool usesSpecMap     = mat.GetTexture("_SpecularMap");
            bool usesGlossMap    = mat.GetTexture("_GlossMap");
            bool usesEmissionMap = mat.GetTexture("_EmissionMap");

            ShaderGUIUtils.SetKeyword(mat, "_USEBUMPMAP_ON", usesBumpMap);
            ShaderGUIUtils.SetKeyword(mat, "_USESPECULARMAP_ON", usesSpecMap);
            ShaderGUIUtils.SetKeyword(mat, "_USEGLOSSMAP_ON", usesGlossMap);

            ShaderGUIUtils.SetKeyword(mat, "_USEEMISSIONMAP_ON", usesEmissionMap);

            if (usesBumpMap || usesSpecMap || usesGlossMap || usesEmissionMap)
            {
                mat.SetFloat("_ForcePerPixel", 1.0f);
            }

            var  texScaleOffset = mat.GetVector("_TextureScaleOffset");
            bool usesScale      = texScaleOffset.x != 1.0f || texScaleOffset.y != 1.0f;
            bool usesOffset     = texScaleOffset.z != 0.0f || texScaleOffset.w != 0.0f;

            ShaderGUIUtils.SetKeyword(mat, "_MainTex_SCALE_ON", usesScale);
            ShaderGUIUtils.SetKeyword(mat, "_MainTex_OFFSET_ON", usesOffset);
        }
        public static void SetScaleOffsetKeywords
        (
            MaterialEditor matEditor,
            MaterialProperty textureProp,
            MaterialProperty scaleOffsetProp
        )
        {
            var  texScaleOffset = scaleOffsetProp.vectorValue;
            bool usesScale      = texScaleOffset.x != 1.0f || texScaleOffset.y != 1.0f;
            bool usesOffset     = texScaleOffset.z != 0.0f || texScaleOffset.w != 0.0f;

            var mat = matEditor.target as Material;

            var scaleKeyword  = textureProp.name + "_SCALE_ON";
            var offsetKeyword = textureProp.name + "_OFFSET_ON";

            ShaderGUIUtils.SetKeyword(mat, scaleKeyword, usesScale);
            ShaderGUIUtils.SetKeyword(mat, offsetKeyword, usesOffset);
        }
        protected virtual void SetMaterialBlendMode(Material mat, BlendMode blendMode)
        {
            switch (blendMode)
            {
            case BlendMode.Opaque:
                mat.SetOverrideTag("RenderType", "");
                mat.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                mat.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                mat.SetInt("_ZWrite", 1);
                ShaderGUIUtils.SetKeyword(mat, "_ALPHATEST_ON", false);
                mat.renderQueue = -1;
                break;

            case BlendMode.Cutout:
                mat.SetOverrideTag("RenderType", "TransparentCutout");
                mat.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                mat.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                mat.SetInt("_ZWrite", 1);
                ShaderGUIUtils.SetKeyword(mat, "_ALPHATEST_ON", true);
                mat.renderQueue = (int)UnityEngine.Rendering.RenderQueue.AlphaTest;
                break;

            case BlendMode.Transparent:
                mat.SetOverrideTag("RenderType", "Transparent");
                //non pre-multiplied alpha
                mat.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                mat.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                mat.SetInt("_ZWrite", 1);
                ShaderGUIUtils.SetKeyword(mat, "_ALPHATEST_ON", false);
                mat.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
                break;

            case BlendMode.Advanced:
                //user configured
                break;
            }
        }