Access material from code that was overridden in URP Renderer

Hello!

I have a URP Renderer which is used to add a hologram effect to some objects by overriding material for targets in a layer mask. However, now I need to access this overridden material from code to change its color, but I only seem to be able to access the default material for the object though. How do I access the overridden material from code?

Thanks!

Needs more info, perhaps a code snippet. Is this about Material Property Blocks? Or as simple as accessing .material rather than .sharedMaterial?

Thanks for the reply.

I’m using the Universal Render Pipeline (URP), not Material Property Blocks.

I have an object called “Avatar” which has a material called “AvatarBody” as default. Sometimes, I set its layer to “Hologram” which adds a hologram effect using RenderObjects in URP.

Now, if I execute the following snippet after adding the hologram layer to an avatar,
Debug.Log(_currentAvatar.gameObject.GetComponentInChildren<Renderer>().materials)
it will only return the “AvatarBody” material, not the “Hologram” material, even though I can see it is added to the Avatar.

8490875--1129583--upload_2022-10-5_11-16-27.png

Hmmm I’m not familiar with RenderObjects. But from the looks of it, this Hologram material does not seem to be part of the MeshRenderer material list. You probably need to access the RenderObjects instance in some way and access its override material property.

Since the object is on the Hologram layer, you can use the layer to determine if it is currently using that RenderObject material - in case RenderObject is a global object, like ScriptableObject.

I encountered the same issue. A solution from ChatGPT helped me — I'm sharing it here.

:white_check_mark: How to Use Different Shader Parameters Per Object with a Single URP Renderer Feature (Without Using Layers)

Context:
You’re using URP and a Renderer Feature (e.g., a RenderObjects pass) to apply an outline shader effect. You want to use different parameters (like color or thickness) on different objects without duplicating layers or materials.
:wrench: Goal:

Apply a single override material via Renderer Feature, but still have unique shader parameters per object, such as different outline colors or thicknesses.
:white_check_mark: Solution: Use Shader Graph Instanced Properties with MaterialPropertyBlock

Unity’s GPU Instancing lets you override shader properties per object while still sharing the same material.
:small_blue_diamond: Step-by-Step:

  1. In Shader Graph:

    Create your shader normally.

    Add properties such as:

     _OutlineColor (Color)
    
     _OutlineThickness (Float)
    

    For each property:

     Enable Exposed
    
     Set HLSL Declaration → Per-Instance (under the property’s gear icon)
    
     This enables GPU Instancing
    
  2. In URP Renderer Feature:

    Use a single Override Material with your Shader Graph material

    Set up the filtering (by tag, render queue, etc.)

  3. On the Object (via script):

Use MaterialPropertyBlock to assign different values per object:

[RequireComponent(typeof(Renderer))]
public class OutlineInstance : MonoBehaviour
{
    public Color outlineColor = Color.cyan;
    public float outlineThickness = 2f;

    private MaterialPropertyBlock mpb;
    private Renderer rend;

    void Awake()
    {
        rend = GetComponent<Renderer>();
        mpb = new MaterialPropertyBlock();
    }

    void Update()
    {
        mpb.SetColor("_OutlineColor", outlineColor);
        mpb.SetFloat("_OutlineThickness", outlineThickness);
        rend.SetPropertyBlock(mpb);
    }
}

:white_check_mark: Even though you’re using an override material via a Renderer Feature, Unity will respect the MaterialPropertyBlock for that object’s renderer.

:pushpin: Summary:
Method___________________________________Works with Renderer Feature?___Requires Extra Layers?
GPU Instancing + MaterialPropertyBlock__✅ Yes___________________________❌ No
Duplicating Materials per Object___________✅ Yes___________________________❌ No (but wasteful)
MaterialPropertyBlock only________________❌ Not for Feature overrides_____❌ No