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.

MaterialPropertyBlock.SetTexture not working for custom URP shader code

Discussion in 'Universal Render Pipeline' started by monark, Aug 24, 2021.

  1. monark

    monark

    Joined:
    May 2, 2008
    Posts:
    1,593
    So I've run into this strange issue with using MaterialPropertyBlock.SetTexture on a custom shader.
    Is there some special way to specify in your shader properties that a texture can be set using this method?

    When I test it on the Unity SimpleUnlit material it works as expected but when I apply it to my own shader it totally fails.
    I can use Material.SetTexture with the same parameter and Texture2D and that works fine, but using a MaterialPropertyBlock it doesn't. At the same time I can update ints, floats, and vectors with a property block totally ok, just not textures.

    Shader property is defined like this:
    Code (CSharp):
    1.  
    2. [NoScaleOffset] _Weights("Weights", 2D) = "white" {}
    3. _Frame("Frame", Float) = 0
    4. _Imagesize("ImageSize", Vector) = (400,150,0,0)
    5.  
    and I'm overriding like this at runtime
    Code (CSharp):
    1.  
    2. Renderer rend = obj.transform.GetComponent<Renderer>();
    3. propBlock = new MaterialPropertyBlock();
    4. rend.GetPropertyBlock(propBlock);
    5. propBlock.SetTexture("_Weights", tex);
    6. propBlock.SetVector("_Imagesize", size);
    7. propBlock.SetInt("_Frame", 1);
    8. rend.SetPropertyBlock(propBlock);
    9.  
    that fails whilst this works
    Code (CSharp):
    1.  
    2. Renderer rend = obj.transform.GetComponent<Renderer>();
    3. Material[] mats = rend.sharedMaterials;
    4. mats[0].SetTexture("_Weights", tex);
    5.  
    So I know the issue isn't in the texture2d it's just not getting set by the property block.

    and if I change the material to a SimpleUnlit I can set the _BaseMap to my texture using the same property block code, just changing the parameter name, so the code is ok. It has to be in the shader, right?

    What am I missing?
     
  2. monark

    monark

    Joined:
    May 2, 2008
    Posts:
    1,593
    Arrgh, so it wasn't either of those things, it was down to doing the changes in a coroutine and only doing the SetPropertyBlock at the end by which point the propBlock was invalid and needed getting again off the renderer.
    The simplified code above doesn't show there are some intermediate yields that were messing it up.
    If I apply the properties as I go it works fine.