how to switch a custom shader to opaque to transparent

hi all!
I have my custom shader derived from the StandardSpecular shader…
In the editor I made a checkbox that set this:

#pragma shader_feature USE_TRANSPARENT_VERTEX

and works, for example in the shader I have this:

#if defined(USE_TRANSPARENT_VERTEX)
    o.Alpha = IN.color.a;
#endif

my question is: at the moment I set the shader to transparent:

SubShader
{
    Tags{ "RenderType" = "Transparent" }
    CGPROGRAM
    #pragma surface surf StandardSpecular fullforwardshadows addshadow alpha:fade

is there a way to switch these settings reading the definition of USE_TRANSPARENT_VERTEX??

thanks in advance

Maybe this can be done with shader keywords and you enable/disable them via script. Haven’t tested, but could work.

Yes it should work.

Keep in mind that once your shader compiled, Unity split it in several shaders for each possibility of compilation condition you have.

You can use Material.EnableKeyword to switch on/off a keyword, Unity will switch to another version of your shader that contain the piece of code in your condition.

You should first check how Unity use keywords by tracing how Emission is done in the standard shader for example.

thanks @pahe and @Fabian-Haquin , seems to work but I need to add the alpha:fade in the #pragma declaration…

in my shader editor I added this:

if (EditorGUI.EndChangeCheck())
{
    Material material = materialEditor.target as Material;
    if (useTransparentVertex.floatValue == 0.0f)
    {
        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;
        material.SetFloat("_Mode", 0.0f);
    }
    else
    {
        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 = (int)UnityEngine.Rendering.RenderQueue.Transparent;
        material.SetFloat("_Mode", 2.0f);
    }
}
1 Like

I never used the Surface Shader version, I always modify the standard shader itself but if it works for you it’s nice! :slight_smile:

On URP you can use this to change The surface type to Transparent

       material.SetFloat("_Surface", 1);
       material.SetInt("_ZWrite", 0);  
       material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
       material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
       material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
1 Like