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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Resolved Runtime transparency & materials instanciation

Discussion in 'High Definition Render Pipeline' started by Thibault_potier, Nov 11, 2021.

  1. Thibault_potier

    Thibault_potier

    Joined:
    May 4, 2021
    Posts:
    46
    Hi

    I'm working with HDRP in unity 2020.3.14

    I'm trying to make runtime transparency. To do so, I modified a shader with shader graph (HDRP/AutodekInteractive) to fit my needs. The detail of my shader modifications is here : https://forum.unity.com/threads/opacity-map-in-hdrp-shader-graph.1195813/ (sorry but as the number of screenshots per post is limited, I cannot just paste it again here). The shader works well.

    So right now I have a custom shader that deals with transparency. But When I'm trying to use it at runtime (I mean create a runtime material and play with the shader parameters) it doesn't behave as intended.

    I made a small demo scene of my problem as an illustration :

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class test_temp_script : MonoBehaviour
    6. {
    7.  
    8.     private Material premadeMaterial;
    9.     private Material runtimeMaterial;
    10.  
    11.     public GameObject cube1;
    12.     public GameObject cube2;
    13.  
    14.     // Start is called before the first frame update
    15.     void Start()
    16.     {
    17.         runtimeMaterial = new Material(Shader.Find("HDRP/Autodesk Interactive/AutodeskInteractiveCustom"));
    18.         runtimeMaterial.EnableKeyword("_OpacityMap");
    19.         runtimeMaterial.EnableKeyword("_UseOpacityMap");
    20.         runtimeMaterial.EnableKeyword("_Opacity");
    21.  
    22.         premadeMaterial = Instantiate(Resources.Load<Material>("TransparentMaterial"));
    23.  
    24.         cube1.GetComponent<Renderer>().material = runtimeMaterial;
    25.         cube2.GetComponent<Renderer>().material = premadeMaterial;
    26.  
    27.         runtimeMaterial.SetInt("_UseColorMap", 0);
    28.         runtimeMaterial.SetColor("_Color", Color.green);
    29.  
    30.         premadeMaterial.SetInt("_UseColorMap", 0);
    31.         premadeMaterial.SetColor("_Color", Color.green);
    32.     }
    33.  
    34.  
    35.     public void setTransparent()
    36.     {
    37.         // ---------------------------------------------------------- CUBE 1 (runtime mat)
    38.  
    39.         Debug.Log("------------------------------------ base values :");
    40.  
    41.         Debug.Log(runtimeMaterial.GetInt("_UseOpacityMap"));
    42.         Debug.Log(runtimeMaterial.GetColor("_Opacity"));
    43.         Debug.Log(runtimeMaterial.GetTexture("_OpacityMap"));
    44.         Debug.Log(runtimeMaterial.GetFloat("_SurfaceType"));
    45.  
    46.         Debug.Log("------------------------------------ new values :");
    47.  
    48.         runtimeMaterial.SetInt("_UseOpacityMap",0);
    49.         runtimeMaterial.SetColor("_Opacity", Color.gray);
    50.  
    51.         Debug.Log(runtimeMaterial.GetInt("_UseOpacityMap"));
    52.         Debug.Log(runtimeMaterial.GetColor("_Opacity"));
    53.         Debug.Log(runtimeMaterial.GetTexture("_OpacityMap"));
    54.         Debug.Log(runtimeMaterial.GetFloat("_SurfaceType"));
    55.  
    56.         // ---------------------------------------------------------- CUBE 2 (premade mat)
    57.  
    58.         premadeMaterial.SetInt("_UseOpacityMap", 0);
    59.         premadeMaterial.SetColor("_Opacity", Color.gray);
    60.     }
    61. }
    at runtime, when I call "setTransparent()" I expect the 2 cubes to look the same. But here is what happen:

    upload_2021-11-11_10-3-45.png

    While the cube2 (with the "premadeMaterial" in my code) behave as expected, the cube 1 doesn't get transparent. But according to the console, the material "knows" the correct values, so I don't understand why it doesn't work

    upload_2021-11-11_10-6-48.png

    Moreover, as soon as I click to expend my cube1 material in the inspector, cube1 suddently become transparent !

    upload_2021-11-11_10-8-29.png
    upload_2021-11-11_10-8-49.png

    Of course I spent the last couple of days googling about this problem, but the conclusion of all the informations I gathered was, that those lines
    Code (CSharp):
    1. runtimeMaterial.EnableKeyword("_OpacityMap");
    2. runtimeMaterial.EnableKeyword("_UseOpacityMap");
    3. runtimeMaterial.EnableKeyword("_Opacity");
    should have solved the problem. But it did not :(

    PS: I also tried with this instead :
    Code (CSharp):
    1. runtimeMaterial.EnableKeyword("OpacityMap");
    2.         runtimeMaterial.EnableKeyword("UseOpacityMap");
    3.         runtimeMaterial.EnableKeyword("Opacity");
    But the result is the same
     
  2. Thibault_potier

    Thibault_potier

    Joined:
    May 4, 2021
    Posts:
    46
    I successfully made it works by instantiating the material this way :
    Code (CSharp):
    1. runtimeMaterial = new Material(Shader.Find("HDRP/Autodesk Interactive/AutodeskInteractiveCustom"));
    2.  
    3.         runtimeMaterial.EnableKeyword("_DISABLE_DECALS");
    4.         runtimeMaterial.EnableKeyword("_DISABLE_SSR_TRANSPARENT");
    5.         runtimeMaterial.EnableKeyword("_ENABLE_FOG_ON_TRANSPARENT");
    6.         runtimeMaterial.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
    7.  
    8.         runtimeMaterial.SetFloat("_SurfaceType", 1f);
    9.         runtimeMaterial.SetFloat("_SrcBlend", (float)UnityEngine.Rendering.BlendMode.One);
    10.         runtimeMaterial.SetFloat("_DstBlend", (float)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
    11.         runtimeMaterial.SetFloat("_ZWrite", 1.0f);
    12.         runtimeMaterial.DisableKeyword("_ALPHATEST_ON");
    13.         runtimeMaterial.DisableKeyword("_ALPHABLEND_ON");
    14.         runtimeMaterial.EnableKeyword("_ALPHAPREMULTIPLY_ON");
    15.         runtimeMaterial.renderQueue = 3000;
    I found those keywords to add ("_DISABLE_DECALS", "_DISABLE_SSR_TRANSPARENT", "_ENABLE_FOG_ON_TRANSPARENT" and "_SURFACE_TYPE_TRANSPARENT" by looking at the "premade material" in debug mode
     
    PutridEx likes this.