Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Opaque to Transparency Shader Mode Failing in Build Version

Discussion in 'Editor & General Support' started by renaissanceCoder1, Jul 4, 2015.

  1. renaissanceCoder1

    renaissanceCoder1

    Joined:
    Apr 8, 2015
    Posts:
    127
    I've been stumped on this one for several hours.

    Here's some background:
    I am working on a project that handles character occlusion by fading out objects that come between camera's view of the player. I use the following method to switch the Standard Shader properties around based on whether the material should be opaque of transparent. Everything works perfectly in the editor, but when I build it, I suspect this method is failing. Material colors will still change normally, but there is no transparency in my objects.

    Code (CSharp):
    1. void SetMaterialBlendMode(Material material, string BLEND_MODE)
    2.     {
    3.         switch (BLEND_MODE)
    4.         {
    5.             case "Opaque":
    6.                 material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
    7.                 material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
    8.                 material.SetInt("_ZWrite", 1);
    9.                 material.DisableKeyword("_ALPHATEST_ON");
    10.                 material.DisableKeyword("_ALPHABLEND_ON");
    11.                 material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
    12.                 material.renderQueue = -1;
    13.                 break;
    14.             case "Fade":
    15.                 material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
    16.                 material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
    17.                 material.SetInt("_ZWrite", 0);
    18.                 material.DisableKeyword("_ALPHATEST_ON");
    19.                 material.EnableKeyword("_ALPHABLEND_ON");
    20.                 material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
    21.                 material.renderQueue = 3000;
    22.                 break;
    23.             case "Transparent":
    24.                 material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
    25.                 material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
    26.                 material.SetInt("_ZWrite", 0);
    27.                 material.DisableKeyword("_ALPHATEST_ON");
    28.                 material.DisableKeyword("_ALPHABLEND_ON");
    29.                 material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
    30.                 material.renderQueue = 3000;
    31.                 break;
    32.         }
    33.     }
    After searching around, I have found a few solutions that do not work for me. Here is what I have tried:

    Placing relevant assets in the Resources folder. (Shader, Material, Prefab) (no change)
    Adding the standard shader to the "Always include" setting in the Graphics Settings. (causes freeze during build)
    Building on different architecture setting. (no change)
     
    Last edited: Sep 1, 2015
    Rob-A likes this.
  2. renaissanceCoder1

    renaissanceCoder1

    Joined:
    Apr 8, 2015
    Posts:
    127
    Still no solution found. Any help or direction would be appreciated.
     
  3. renaissanceCoder1

    renaissanceCoder1

    Joined:
    Apr 8, 2015
    Posts:
    127
    Solved the issue. In case anyone else runs into this...
    If you plan to swap shaders at run-time, the shaders need to be in the scene when you build the project. In other words, I did not have a transparency shader on any objects. I just added a cube to the scene with a transparent shader and viola it worked.
     
    miracletechteam1 and dmonin like this.
  4. dmonin

    dmonin

    Joined:
    Jun 14, 2015
    Posts:
    28
    Thats strange but your advice doesnt work for me.
     
  5. fffMalzbier

    fffMalzbier

    Joined:
    Jun 14, 2011
    Posts:
    3,276
    Zhnz, Issus94 and dmonin like this.
  6. dmonin

    dmonin

    Joined:
    Jun 14, 2015
    Posts:
    28
  7. miracletechteam1

    miracletechteam1

    Joined:
    Sep 18, 2019
    Posts:
    24
    OMG THANK YOU IT WORKS in Unity 2020.3.21.f1 !!
    Also, if u want to change the texture... insert a dummy texture into that cube. Otherwise it won't work
     
  8. Issus94

    Issus94

    Joined:
    Nov 22, 2021
    Posts:
    6
    Unfortunately, the trick of simply packing a GameObject into the scene with the Standard shader and Rendering Mode set to Transparent doesn't work for me. In the Unity Editor I can change the transparency of the objects without any problems in runtime, but in the build version nothing happens. Did anyone have the same problem and a solution?
     
    StellarVeil likes this.
  9. StellarVeil

    StellarVeil

    Joined:
    Aug 31, 2018
    Posts:
    73
    Same problem and no solution yet sadly :3
    Unity 2022.1
     
  10. StellarVeil

    StellarVeil

    Joined:
    Aug 31, 2018
    Posts:
    73
    Update: I found a solution the following day ! (it isn't mentioned anywhere I checked sadly)
    Basically don't change the material's shader instead make a new material copy and assign the Standard shader to it like this (the emission & glossiness parts are optional but safeguards against visual issues, works on Unity 2022.1.12f1 windows build):

    Code (CSharp):
    1. private Material CreateTransparentMaterial(Material origMaterial)
    2.         {
    3.             var material = new Material(origMaterial);
    4.             material.shader = Shader.Find("Standard");
    5.             material.name += "X";
    6.             material.SetFloat("_Mode", 3f);
    7.             material.renderQueue = 3000;
    8.  
    9.             material.DisableKeyword("_EMISSION");
    10.             material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.EmissiveIsBlack;
    11.             material.SetColor(EMISSION_COLOR, Color.black);
    12.  
    13.             material.SetOverrideTag("RenderType", "Transparent");
    14.             material.SetFloat("_SrcBlend", (float)UnityEngine.Rendering.BlendMode.One);
    15.             material.SetFloat("_DstBlend", (float)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
    16.             material.SetFloat("_ZWrite", 0.0f);
    17.             material.DisableKeyword("_ALPHATEST_ON");
    18.             material.DisableKeyword("_ALPHABLEND_ON");
    19.             material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
    20.  
    21.             var col = material.color;
    22.             col.a = ALPHA_TO_APPLY;
    23.             material.color = col;
    24.          
    25.             if (material.HasFloat("_GlossMapScale"))
    26.                 material.SetFloat("_GlossMapScale", 0);
    27.  
    28.             return material;
    29.         }
    You can make the code faster by caching some of the keywords with ints like this:

    private static readonly int SHADER_RENDERING_MODE = Shader.PropertyToID("_Mode");

    Then you do the assignment like this:
    someRenderer.material = CreateTransparentMaterial(someRenderer.material);

    but if this code is to be ran more than once then you should cache the transparentMaterial:

    Code (CSharp):
    1. transpMaterial = CreateTransparentMaterial(someRenderer.material);
    2.  
    3. ---
    4.  
    5. someRenderer.material = transpMaterial;
    If the renderer has multiple materials you just iterate through them and create a transparent copy for each, put them in an array then you just assign the plural version of the mat field:

    someRenderer.materials = transpMaterials;