Search Unity

Runtime setting _NormalMap on HDRP/Lit doesn't work until EditorGUI change

Discussion in 'Shaders' started by max_coding13, Mar 22, 2019.

  1. max_coding13

    max_coding13

    Joined:
    Apr 24, 2016
    Posts:
    34
    I'm setting the _NormalMap property of a HDRP/Lit material during runtime and experiencing strange behavior. After setting the texture, the texture will display in the material editor as if it loaded correctly, but the material itself doesn't show the normal map. However, if I change any value on the material editor, through user input, the material "rebuilds" itself and the normal map displays correctly.

    After looking at the source code I'm guessing this is related to the method EditorGUI.BeginChangeCheck() that the Editor calls on user input.

    Is there a way to hit this same rebuilding process through script after I set my normal map texture?
     
    Last edited: Mar 22, 2019
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,343
    If you look at the Lit.shader itself you'll find a bunch of #pragma shader_feature_local lines. Those are features that can be enabled or disabled on the shader via keywords. You can look at the code for the Lit shader's custom material editor to get an idea of what keywords (or other settings) need to be set for various features. The custom editor only runs while in the editor while you have the material selected. When modifying the material from your own code you need to enable or disable those keywords on the material yourself.

    For a normal map, it looks like you need to enable the "_NORMALMAP" and "_NORMALMAP_TANGENT_SPACE" keywords in addition to setting the texture.

    https://docs.unity3d.com/ScriptReference/Shader.EnableKeyword.html
     
    ModLunar, morepixels and Elecman like this.
  3. max_coding13

    max_coding13

    Joined:
    Apr 24, 2016
    Posts:
    34
    Wow! That's exactly the part the material editor's class I was trying to make sense of when I opened your reply.
    Thank you so much for getting me over the hump.
    To all future readers : enabling those keywords fixed the issue I described.
     
  4. highpockets

    highpockets

    Joined:
    Jan 17, 2013
    Posts:
    71
    This is not working for me. My setup:

    In the editor, while streaming GLB models and setting various properties of the HDRP Lit shader (_NORMALMAP, _NORMALMAP_TANGENT_SPACE, _DOUBLESIDED_ON) the changes are not taking effect.

    I´ve tried using the global Shader.EnableKeyword() for each and the local material.EnableKeyword() as well. The result is always the same. No changes are apparent on the respective game objects in the scene or game views until I select the said game objects and click to open their material to view the shader in the inspector, at which time, the changes magically take effect as if the shader gets recompiled at that time.
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,343
    This was from 3 years ago shortly after the HDRP was first released publicly. The HDRP has changed significantly since then, so there may be additional steps you'd need to take.

    However the overall answer is the same, even if the solution is not. You need to look at the specific shader you're using and that shader's custom material editor code to find out what they're doing and do the same thing.

    It will absolutely be solved by modifying the keywords on the material using
    material.EnableKeyword()
    and not globally via the
    Shader.EnableKeyword()
    . My past self linked to the wrong documentation there.

    However, looking at the current code, it looks like to get normal maps working what you need to do hasn't changed:
    Code (csharp):
    1. material.EnableKeyword("_NORMALMAP");
    2. material.EnableKeyword("_NORMALMAP_TANGENT_SPACE");
    3. material.SetTexture("_NormalMap", normalMapTexture);
     
    highpockets likes this.
  6. highpockets

    highpockets

    Joined:
    Jan 17, 2013
    Posts:
    71
    Fair enough, when I use the local material.EnableKeyword() Normal maps and Mask maps are working, BUT Double Sided is 100% not working and that is the one I was paying most attention to while testing so I just assumed it wasn´t updating the rest, so my apologies because I know this thread is about NormalMaps. The keyword appears to be "_DOUBLESIDED_ON". I am dealing with streaming GLB´s from a 3rd party and have noticed that some normals are flipped on some mesh, so double sided is a must.

    Anyhow, I know this thread was started based on Normal Maps not working, so I opened a new thread while I continue poking at this. Thanks for your prompt reply @bgolus
     
    Last edited: Feb 23, 2022
  7. highpockets

    highpockets

    Joined:
    Jan 17, 2013
    Posts:
    71
    Solved this by setting the cull mode to none. Seems that setting it to double sided doesn´t make that change for you until you click on the material at which time the double sided appears to take preference. Thanks again @bgolus
     
  8. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,343
    Yep. That's why I kept saying you need to look at the custom material inspector, because it's very likely changing several settings at once, not just a keyword.