Search Unity

Access Rendering mode var on Standard Shader via scripting

Discussion in 'Unity 5 Pre-order Beta' started by jmunozar, Dec 22, 2014.

  1. jmunozar

    jmunozar

    Joined:
    Jun 23, 2008
    Posts:
    1,068
    Hey Guys,

    So basically I have been searching (without no luck) how to access the rendering mode in the standard shader; this is purely to be able to classify the type of standard shader is being used.

    I know how to read all the properties, TexEnv Color, Range, and even if a texture is a flat texture type (TexDim2D) but I haven't been able to work out by myself what's the property that defines the Rendering Mode in the standard shader :s

    I'm attaching an image to show exactly what I'm looking for.

    Thanks a lot :)
     

    Attached Files:

    howong likes this.
  2. jmunozar

    jmunozar

    Joined:
    Jun 23, 2008
    Posts:
    1,068
    Guy I even have the properties for the standard shader and as I said there is no ref to a rendering mode (I would guess the rendering mode is an enum).. so .. any idea? :)

    Code (csharp):
    1.  
    2. Shader "Standard"
    3. {
    4.     Properties
    5.     {
    6.         [LM_Albedo] [LM_Transparency] _Color("Color", Color) = (1,1,1,1)  
    7.         [LM_MasterTilingOffset] [LM_Albedo] _MainTex("Albedo", 2D) = "white" {}
    8.      
    9.         [LM_TransparencyCutOff] _AlphaTestRef("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
    10.  
    11.         [LM_Glossiness] _Glossiness("Smoothness", Range(0.0, 1.0)) = 0.0
    12.         [LM_Metallic] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0
    13.         [LM_Metallic] [LM_Glossiness] _MetallicGlossMap("Metallic", 2D) = "white" {}
    14.  
    15.         _BumpScale("Scale", Float) = 1.0
    16.         [LM_NormalMap] _BumpMap("Normal Map", 2D) = "bump" {}
    17.  
    18.         _Parallax ("Height Scale", Range (0.005, 0.08)) = 0.02
    19.         _ParallaxMap ("Height Map", 2D) = "black" {}
    20.  
    21.         _OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0
    22.         _OcclusionMap("Occlusion", 2D) = "white" {}
    23.  
    24.         [LM_Emission] _EmissionColor("Color", Color) = (0,0,0)
    25.         [LM_Emission] _EmissionMap("Emission", 2D) = "white" {}
    26.      
    27.         _DetailMask("Detail Mask", 2D) = "white" {}
    28.  
    29.         _DetailAlbedoMap("Detail Albedo x2", 2D) = "grey" {}
    30.         _DetailNormalMapScale("Scale", Float) = 1.0
    31.         _DetailNormalMap("Normal Map", 2D) = "bump" {}
    32.  
    33.         [KeywordEnum(UV1, UV2)] _UVSec ("UV Set for secondary textures", Float) = 0
    34.  
    35.         // UI-only data
    36.         [KeywordEnum(None, Realtime, Baked)]  _Lightmapping ("GI", Int) = 1
    37.         [HideInInspector] _EmissionScaleUI("Scale", Float) = 1.0
    38.         [HideInInspector] _EmissionColorUI("Color", Color) = (0,0,0)
    39.         [HideInInspector] _EmissionColorWithMapUI("Color", Color) = (1,1,1)
    40.  
    41.         // Blending state
    42.         [HideInInspector] _Mode ("__mode", Float) = 0.0
    43.         [HideInInspector] _SrcBlend ("__src", Float) = 1.0
    44.         [HideInInspector] _DstBlend ("__dst", Float) = 0.0
    45.         [HideInInspector] _ZWrite ("__zw", Float) = 1.0
    46.     }
    47.  
     
  3. jamie-lowes

    jamie-lowes

    Joined:
    Jul 5, 2012
    Posts:
    47
    Near the bottom of the Standard shader there is a reference to an editor script for the UI. That's what controls the "Rendering Mode".
     
  4. jmunozar

    jmunozar

    Joined:
    Jun 23, 2008
    Posts:
    1,068
    ah I see it!, thanks a lot! :). I guess is this one (at the very end of the standard shader tab).

    Code (csharp):
    1.  
    2.     FallBack "VertexLit"
    3.     CustomEditor "StandardShaderGUI"
    4. }
    5.  
    Now unfortunately I haven't been able to see any API call to that script :/, any idea on how to call it to ask?, is this internal?
     
  5. jmunozar

    jmunozar

    Joined:
    Jun 23, 2008
    Posts:
    1,068
    I mean, I know its included in the standard shaders (the StandardShaderGUI.cs) but my question is, how do I access the blendmode for each shader ? :S
    Code (csharp):
    1.  
    2.  public enum BlendMode
    3.     {
    4.         Opaque,
    5.         Cutout,
    6.         Transparent
    7.     }
    8.  
    thanks a lot guys!
     
  6. jmunozar

    jmunozar

    Joined:
    Jun 23, 2008
    Posts:
    1,068
    Guys, found the solution! <3 thanks!.

    The Rendering mode in the standard shader that refers to either Opaque, Cutout or transparent is mapped via the StandardShaderGUI to a float property called _Mode

    so its a matter of getting the float like this:
    Code (csharp):
    1.  
    2. Material mat;//this is the material we want to know its rendering mode
    3. Debug.Log(mat.GetFloat("_Mode"));
    4. //and depending on the number it outputs (0, 1, 2) it maps to Opaque, Cutout and transparent
    5.  
    Again :) thanks!
     
  7. Discord

    Discord

    Joined:
    Mar 19, 2009
    Posts:
    1,002
    Thanks for this! I'm trying to change a material from opaque to transparent at run-time. By using something like:
    Code (csharp):
    1.  
    2. Material mat = GetComponentInChildren<SkinnedMeshRenderer>().materials[0];
    3.         mat.SetFloat("_Mode", 2.0f);
    it changes the rendering mode in the inspector, but in-game, it's still opaque! If I manually change it in the inspector instead of in the code, it works as expected. Does anyone know if you have to refresh the shader or something along those lines? Thanks.
     
  8. jmunozar

    jmunozar

    Joined:
    Jun 23, 2008
    Posts:
    1,068
    ah, something like that similarly happened to me when I wanted to change some values in materials.

    Try out using sharedMaterials instead of materials :)!, and if that doesnt work for you try out loading the Material from the project view (if possible)
     
  9. HarpSeal1

    HarpSeal1

    Joined:
    Oct 23, 2013
    Posts:
    35
    Hi Guys,

    I am trying to set the render mode at runtime as like Discord, using sharedMaterials didn't help. Has anyone found a work around? Thanks so much! I can actually see the values in the inspector change, but the material won't show the change!
     
  10. jmunozar

    jmunozar

    Joined:
    Jun 23, 2008
    Posts:
    1,068
    Hey @HarpSeal1 did you tried loading the material from the project view? (and then accessing the sharedMaterial), that should solve your issue me thinks...

    if it doesnt let me know I try some things here and check what can I come up with ;)
     
  11. HarpSeal1

    HarpSeal1

    Joined:
    Oct 23, 2013
    Posts:
    35
    Hi Jmunozar, Thanks for the reply. I've tried using sharedMaterials and assigning material from project view. It seems the alpha value in albedo color isn't updating in the viewport, but the Inspector value is correct. Once i move the alpha value in the inspector even 1 it will update. Thanks for you help!

    Ah! I found the problem. Use:
    Code (CSharp):
    1. Material.SetColor("_Color", yourColor);
    I was trying to use:
    Code (CSharp):
    1. Material.color = yourColor;
    Strange, maybe i should file a bug?
     
    Last edited: Jan 7, 2015
  12. jmunozar

    jmunozar

    Joined:
    Jun 23, 2008
    Posts:
    1,068
    AHH its a bug! I already reported it in the last Unity5 Beta!, and they said they will fix it in the new beta; if you click on the material in the project view it should be fixed :).

    STILL... do you have a small video you can share so I can see if its the same bug? :p
     
    MartinLyne likes this.
  13. HarpSeal1

    HarpSeal1

    Joined:
    Oct 23, 2013
    Posts:
    35
    Yeah it must be a bug, it works fine on some runs, then breaks on others until I edit it in the Inspector. Of course, here is a video. I hope there is a new beta soon :/
     

    Attached Files:

  14. jmunozar

    jmunozar

    Joined:
    Jun 23, 2008
    Posts:
    1,068
    Hey @HarpSeal1 indeed it looks like a bug, it should get the alpha from the very beginning, report it as a bug with repro steps :)
     
  15. northman

    northman

    Joined:
    Feb 28, 2008
    Posts:
    125
    I got the same problem.
    I hope Unity can fix this bug early.
     
  16. JJC1138

    JJC1138

    Joined:
    Feb 23, 2012
    Posts:
    89
    This seems to me to still be broken in 5.0.0f1. I'm attempting to put a material with the standard shader into "Fade" mode from script and this is what I'm doing so far:
    Code (CSharp):
    1.     Material m;
    2.     // [...]
    3.     m.SetFloat("_Mode", 2);
    4.     m.EnableKeyword("_ALPHABLEND_ON");
    5.     m.renderQueue = 3000;
    6.     m.SetColor("_Color", new Color(1, 1, 1, 0.5f));
    7.  
    Should that work? As others in this thread mentioned, if I inspect the material it seems to be in the right mode and with the correct alpha set on the albedo, but it doesn't actually fade in the game view unless I tweak the the alpha in the inspector.

    Has anyone else figured out a way of doing this reliably?
     
    Ali-Nagori and I-am-Lawrence like this.
  17. jmunozar

    jmunozar

    Joined:
    Jun 23, 2008
    Posts:
    1,068
    Hey @JJC1138

    wow, it seems it hasnt been fixed then, even on RC1 :/.........

    I think the best way is to still send a bug report with a small video showing step by step on how to repro this annoying bug :/.

    Unfortunately I havent found a way to overcome this annoying thing :/ even updating the project view doesnt help :/
     
    JJC1138 likes this.
  18. JJC1138

    JJC1138

    Joined:
    Feb 23, 2012
    Posts:
    89
    @jmunozar Ah thanks for the reply! I will file a bug report.
     
  19. jmunozar

    jmunozar

    Joined:
    Jun 23, 2008
    Posts:
    1,068
    no problem :), hopefully it gets fixed by RC2! :/
     
  20. JJC1138

    JJC1138

    Joined:
    Feb 23, 2012
    Posts:
    89
    Eek, I did a bit more digging and it turns out this isn't actually a Unity bug at all. I just wasn't setting all the necessary parameters on the shader. If you download the Built-in Shaders from the beta page you'll find there's a script Editor/StandardShaderGUI.cs, and that has a method SetupMaterialWithBlendMode(Material, BlendMode) that shows how to set it up properly. To switch to fade mode you do:
    Code (CSharp):
    1.                 material.SetFloat("_Mode", 2);
    2.                 material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
    3.                 material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
    4.                 material.SetInt("_ZWrite", 0);
    5.                 material.DisableKeyword("_ALPHATEST_ON");
    6.                 material.EnableKeyword("_ALPHABLEND_ON");
    7.                 material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
    8.                 material.renderQueue = 3000;
     
    Last edited: Feb 12, 2015
  21. jmunozar

    jmunozar

    Joined:
    Jun 23, 2008
    Posts:
    1,068
    oh wow,

    Thanks for sharing :). and I thought it was a bug :(.

    :D Thanks!
     
    JJC1138 likes this.
  22. ReynV

    ReynV

    Joined:
    Sep 24, 2014
    Posts:
    31
    Hi guys,
    Thanks for the info about controlling transparency at runtime.

    I have a problem though, transparency works in the editor but not when I build an .exe or web version.
    I tried making a copy of the standard shader and putting it in my resource folder, but that didn't work.
    I'm not getting any strange output in output_log.txt
    I'v tried different quality settings

    Anyone know what could be going on ?
    Thanks!
     
  23. jmunozar

    jmunozar

    Joined:
    Jun 23, 2008
    Posts:
    1,068
    Hey @ReynV I actually never built anything and tried it out... mmm.

    Why are you putting a copy of the standard shader in your resource folder?, are you sure you are using that reference (the standard shader in the resource folder) tied up to your material in your project?.. that could be the case maybe :)
     
  24. jgilbert

    jgilbert

    Joined:
    Aug 20, 2014
    Posts:
    10
    I tried to do this as well. The problem, as I understand it, is that at build time Unity doesn't know you want a transparent variant. So it gets stripped. In order for this to work, the shader_feature pragmas would have to be switched to multi_compile. Now that isn't really feasible as it bloats the shader up to 200+ MB. What you may want to try is running in the editor and then create a ShaderVariantCollection that you can preload. (http://docs.unity3d.com/500/Documentation/ScriptReference/ShaderVariantCollection.html)
     
    JJC1138 likes this.
  25. jmunozar

    jmunozar

    Joined:
    Jun 23, 2008
    Posts:
    1,068
    Makes total sense, I didn't see any example on how to load a shader variants, but for what I saw it seems you need to load by hand your shader that you set up in the editor via code so you can load it on runtime :/. *auch*
     
  26. jgilbert

    jgilbert

    Joined:
    Aug 20, 2014
    Posts:
    10
    From the docs: "Typical use of ShaderVariantCollection is to record the shader variants used during a play session from the editor (under Graphics Settings), save them out as an asset, and add to the list of preloaded shaders (again in Graphics Settings). Additionally, you could call WarmUp on a ShaderVariantCollection object manually."
     
    JJC1138 likes this.
  27. jmunozar

    jmunozar

    Joined:
    Jun 23, 2008
    Posts:
    1,068
    ah, didnt read that that seems waaay easier :). ty!
     
  28. ReynV

    ReynV

    Joined:
    Sep 24, 2014
    Posts:
    31
    Hi,
    Thanks for the info on shader variants, it makes sense that parts of the shader is being stripped.
    I saved the shader variants after pressing stop in the editor and added it to the preloaded shaders list.

    Unfortunately I still don't have runtime transparency.

    This is what my shader variant looks like.
    The material that should fade has the Standard shader associated to it.


    Could it be that something missing from my shader variant ?

    Thanks!
     
    JJC1138 likes this.
  29. JJC1138

    JJC1138

    Joined:
    Feb 23, 2012
    Posts:
    89
    @ReynV That looks to me like it should work, but it fails for me too and I don't know why. As a workaround I made a duplicate of the material I need and set it to fade mode in the editor, and then added an inactive GameObject to one of my scenes and made it use that fade-mode material. That seems to have forced the right shader to be included in the build and made switching the original material to fade mode at runtime work. Bit ugly, but it works.
     
    howong and theolagendijk like this.
  30. ReynV

    ReynV

    Joined:
    Sep 24, 2014
    Posts:
    31
    @JJC1138 Excellent thanks that worked!
     
    JJC1138 likes this.