A Defect or BUG of Unity Standard Shader GUI

I’m trying to write my own shader GUI. And while I’m studying the StandardShaderGUI, I found something wrong.
It all come from the codes below (you can find it in builtin_shaders_5.x/Editor/StandardShaderGUI.cs):

public static void SetupMaterialWithBlendMode(Material material, BlendMode blendMode)
    {
        switch (blendMode)
        {
            case BlendMode.Opaque:
                material.SetOverrideTag("RenderType", "");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                material.SetInt("_ZWrite", 1);
                material.DisableKeyword("_ALPHATEST_ON");
                material.DisableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = -1;
                break;
            case BlendMode.Cutout:
                material.SetOverrideTag("RenderType", "TransparentCutout");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                material.SetInt("_ZWrite", 1);
                material.EnableKeyword("_ALPHATEST_ON");
                material.DisableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = 2450;
                break;
            case BlendMode.Fade:
                material.SetOverrideTag("RenderType", "Transparent");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                material.SetInt("_ZWrite", 0);
                material.DisableKeyword("_ALPHATEST_ON");
                material.EnableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = 3000;
                break;
            case BlendMode.Transparent:
                material.SetOverrideTag("RenderType", "Transparent");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                material.SetInt("_ZWrite", 0);
                material.DisableKeyword("_ALPHATEST_ON");
                material.DisableKeyword("_ALPHABLEND_ON");
                material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = 3000;
                break;
        }
    }

So according to the code above, renderQueue is manually set to 3000/2450 when the BlendMode is not Opaque. I don’t know why it doesn’t use SetOverrideTag method to set renderQueue instead. The result is that if you first set a material’s shader to standard shader with none-opaque mode and then switch shader to other, bingo, the material’s renderQueue leaves with no care and your shader’s Queue tag will be overrided. So if your next shader is an opaque shader, that’s fine, because ztest still works, just losing some performance. However if the shader has a custom Queue tag, say “Tranparent+1” for example, that would be a disaster. The rendering result will be incorrect and it’s hard to locate the reason. And it would be a painfully task to check all the materials in debug view to see if it’s renderqueue is overrided. That must be a BUG.

btw, my Unity version is 5.1.1p4, maybe it’s been resolved in later version?

This just caused issues for me as well. I wouldn’t expect that changing from shader A to B then back to A, all without doing anything, would change any of the properties on the material.

At the very least, this should be exposed through the UI in a reasonable way, so that I can see it happening.

After write my own shader GUI, I found this problem is kind of tricky. Unity doing this because the want to make it convenient when your switch shaders. Shader properties are stay so the material can fill in most of the properties automatically when new shader is applied. I think Unity should change it like this. Only explicit shader properties (visible in inspector) and the inplicit shader properties for both shaders should be kept when changing shader. All the inplicit properties which only old shader have should be removed.