Search Unity

how to switch a custom shader to opaque to transparent

Discussion in 'Shaders' started by ghiboz, Jul 25, 2017.

  1. ghiboz

    ghiboz

    Joined:
    Sep 7, 2012
    Posts:
    465
    hi all!
    I have my custom shader derived from the `StandardSpecular` shader..
    In the editor I made a checkbox that set this:
    Code (CSharp):
    1. #pragma shader_feature USE_TRANSPARENT_VERTEX
    and works, for example in the shader I have this:
    Code (CSharp):
    1. #if defined(USE_TRANSPARENT_VERTEX)
    2.     o.Alpha = IN.color.a;
    3. #endif
    my question is: at the moment I set the shader to transparent:
    Code (CSharp):
    1. SubShader
    2. {
    3.     Tags{ "RenderType" = "Transparent" }
    4.     CGPROGRAM
    5.     #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
     
  2. pahe

    pahe

    Joined:
    May 10, 2011
    Posts:
    543
    Maybe this can be done with shader keywords and you enable/disable them via script. Haven't tested, but could work.
     
  3. Fabian-Haquin

    Fabian-Haquin

    Joined:
    Dec 3, 2012
    Posts:
    231
    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.
     
  4. ghiboz

    ghiboz

    Joined:
    Sep 7, 2012
    Posts:
    465
    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:
    Code (CSharp):
    1. if (EditorGUI.EndChangeCheck())
    2. {
    3.     Material material = materialEditor.target as Material;
    4.     if (useTransparentVertex.floatValue == 0.0f)
    5.     {
    6.         material.SetOverrideTag("RenderType", "");
    7.         material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
    8.         material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
    9.         material.SetInt("_ZWrite", 1);
    10.         material.DisableKeyword("_ALPHATEST_ON");
    11.         material.DisableKeyword("_ALPHABLEND_ON");
    12.         material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
    13.         material.renderQueue = -1;
    14.         material.SetFloat("_Mode", 0.0f);
    15.     }
    16.     else
    17.     {
    18.         material.SetOverrideTag("RenderType", "Transparent");
    19.         material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
    20.         material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
    21.         material.SetInt("_ZWrite", 0);
    22.         material.DisableKeyword("_ALPHATEST_ON");
    23.         material.EnableKeyword("_ALPHABLEND_ON");
    24.         material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
    25.         material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
    26.         material.SetFloat("_Mode", 2.0f);
    27.     }
    28. }
     
    HarvesteR likes this.
  5. Fabian-Haquin

    Fabian-Haquin

    Joined:
    Dec 3, 2012
    Posts:
    231
    I never used the Surface Shader version, I always modify the standard shader itself but if it works for you it's nice! :)
     
  6. DhiaSendi

    DhiaSendi

    Joined:
    May 16, 2018
    Posts:
    42
    On URP you can use this to change The surface type to Transparent
    Code (CSharp):
    1.        material.SetFloat("_Surface", 1);
    2.        material.SetInt("_ZWrite", 0);  
    3.        material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
    4.        material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
    5.        material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
    6.