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

Question How can I expose 'Surface Type' in shader graph

Discussion in 'Shader Graph' started by hawaiian_lasagne, Apr 5, 2020.

  1. hawaiian_lasagne

    hawaiian_lasagne

    Joined:
    May 15, 2013
    Posts:
    120
    Hi

    The Universal Render Pipeline/Lit shader has a 'Surface Type' property for making something transparent/opaque. In shader graph, it only seems possible to set this directly on the PBR master node.

    Is it possible to add this to the blackboard somehow to expose it?
     
    The_Swiss_Guy likes this.
  2. spiegelball

    spiegelball

    Joined:
    Mar 2, 2020
    Posts:
    16
    You can set this via .SetInt("_SurfaceType", ...) without manual exposing per material. Note that you also have to set the render queue accordingly.

    Transparent:
    .SetInt("_SurfaceType", 1);
    .SetInt("_RenderQueueType", 4);

    Opaque:
    .SetInt("_SurfaceType", 0);
    .SetInt("_RenderQueueType", 1);

    Edit: I don't remember how I figured out which are the right numbers. Maybe debugging...
     
    hawaiian_lasagne likes this.
  3. hawaiian_lasagne

    hawaiian_lasagne

    Joined:
    May 15, 2013
    Posts:
    120
    Thank you this worked perfectly!
     
  4. spiegelball

    spiegelball

    Joined:
    Mar 2, 2020
    Posts:
    16
    I just discovered that in my case A LOT more shader flags have to be set and that only the transparent -> opaque conversion worked with the subset of flags shared earlier.

    Transparent:
    Code (CSharp):
    1. transparentMat.EnableKeyword("_BLENDMODE_ALPHA");
    2. transparentMat.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
    3. transparentMat.EnableKeyword("_ENABLE_FOG_ON_TRANSPARENT");
    4. transparentMat.DisableKeyword("_BLENDMODE_ADD");
    5. transparentMat.DisableKeyword("_BLENDMODE_PRE_MULTIPLY");
    6.  
    7. transparentMat.SetFloat("_SurfaceType", (int)SurfaceType.Transparent);
    8. transparentMat.SetFloat("_RenderQueueType", 5);
    9. transparentMat.SetFloat("_BlendMode", 0);
    10. transparentMat.SetFloat("_AlphaCutoffEnable", 0);
    11. transparentMat.SetFloat("_SrcBlend", 1f);
    12. transparentMat.SetFloat("_DstBlend", 10f);
    13. transparentMat.SetFloat("_AlphaSrcBlend", 1f);
    14. transparentMat.SetFloat("_AlphaDstBlend", 10f);
    15. transparentMat.SetFloat("_ZTestDepthEqualForOpaque", 4f);
    16.  
    17. transparentMat.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
    Opaque:
    Code (CSharp):
    1. opaqueMat.SetInt("_SurfaceType"_STRING, (int)SurfaceType.Opaque);
    2. opaqueMat.SetInt("_RenderQueueType", (int)1);
    3. opaqueMat.SetFloat("_AlphaDstBlend", 0f);
    4. opaqueMat.SetFloat("_DstBlend", 0f);
    5. opaqueMat.SetFloat("_ZTestDepthEqualForOpaque", 3f);
    6. opaqueMat.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Geometry;
     
    Last edited: Apr 14, 2020
  5. youngjinna97

    youngjinna97

    Joined:
    Nov 23, 2020
    Posts:
    2
    Code (CSharp):
    1. void ViewObstructed()
    2.     {
    3.         RaycastHit hit;
    4.         if(Physics.Raycast(transform.position, target.position - transform.position, out hit))
    5.             if(hit.collider.gameObject.name != HitObj)
    6.             {
    7.                 Obstruction.gameObject.GetComponent<MeshRenderer>().material.SetInt("_SurfaceType", 0);
    8.                 Obstruction.gameObject.GetComponent<MeshRenderer>().material.SetFloat("Vector1_2B798094", 1f);
    9.             }
    10.  
    11.             if(hit.collider.gameObject.tag != "Player")
    12.             {
    13.                 Obstruction = hit.transform;
    14.                 Obstruction.gameObject.GetComponent<MeshRenderer>().material.SetInt("_SurfaceType", 1);
    15.                 Obstruction.gameObject.GetComponent<MeshRenderer>().material.SetFloat("Vector1_2B798094", 0.3f);
    16.                 HitObj = hit.collider.gameObject.name;
    17.             }
    18.             else
    19.             {
    20.                 Obstruction.gameObject.GetComponent<MeshRenderer>().material.SetInt("_SurfaceType", 0);
    21.                 Obstruction.gameObject.GetComponent<MeshRenderer>().material.SetFloat("Vector1_2B798094", 1f);
    22.             }
    23.         }
    24.     }
    Obstruction.gameObject.GetComponent<MeshRenderer>().material.SetInt("_SurfaceType", 0);
    it's for Opaque surface of PBR Master.

    Obstruction.gameObject.GetComponent<MeshRenderer>().material.SetInt("_SurfaceType", 1);
    it's for Transparent surface of PBR Master.

    but i dont know it doesnt work.. please help me..
     
    hawaiian_lasagne likes this.
  6. youngjinna97

    youngjinna97

    Joined:
    Nov 23, 2020
    Posts:
    2
    ohh,, of course i also add it too..
    Obstruction.gameObject.GetComponent<MeshRenderer>().material..SetInt("_RenderQueueType", 4);
    Obstruction.gameObject.GetComponent<MeshRenderer>().material..SetInt("_RenderQueueType", 1);
     
    hawaiian_lasagne likes this.
  7. hawaiian_lasagne

    hawaiian_lasagne

    Joined:
    May 15, 2013
    Posts:
    120
  8. Helaly96

    Helaly96

    Joined:
    Mar 29, 2020
    Posts:
    8
    this didn't work for me at all
     
  9. Helaly96

    Helaly96

    Joined:
    Mar 29, 2020
    Posts:
    8
    these do get changed but they have no effect
     
  10. binoman

    binoman

    Joined:
    Sep 29, 2016
    Posts:
    13
    I must be missing something. Sorry for my n00bness, but you're all talking about code where the Shader graph is, well, a graph tool for shaders. What am I missing? where do you implement the code you all talk about?
     
    ddabble likes this.
  11. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    4,013
    I don't when this might have changed, but I tried this in Unity 2021 and there was no such value as _SurfaceType, but if you change it to _Surface then it works.
     
  12. gwelkind

    gwelkind

    Joined:
    Sep 16, 2015
    Posts:
    65
    I missed this at first too. He's saying instead of setting this in ShaderGraph as a variable, you don't need to do this, because ALL URP materials have these variables dynamically defined.

    i.e., why would we want a variable? So we can change it in C#, right? Well, we can change it in C# without declaring a variable.
     
  13. gwelkind

    gwelkind

    Joined:
    Sep 16, 2015
    Posts:
    65
    I made a new solution for this problem for a custom shader graph built on lit.

    What I've done to solve the problem, which feels a bit more reliable to me, is just to make two shaders (one transparent, one opaque), then, when I need to toggle at runtime (or from within the materials editor) I just do `material.shader = Shader.Find("Transparent_counterpart")`

    All of the prop values get transferred seamlessly, and, presumably, this will work across versions. I think it should be the recommended method, even though it creates some duplicate code/graph.