UI image material does not return instanced material

Here’s what I did: I made a shader graph to create a morphing pattern; created the material and put it on a UnityEngine.UI.Image; tried to control it by setting it’s material parameters. However, when I write to it’s material it writes directly to the material in file, instead of the instanced material for the image.

What I had to do instead is to create an instance of the material at Start and replace the original with it. This is quite cumbersome, though.

I am aware that MeshRenderer has a material property and a sharedMaterial property. So why is it different with UI images? Is this intended or bug? And if intended, why?

2 Likes

There’s a lot that goes on behind the scenes with UI materials because of the batching, masking, canvases, etc. You should be able to set the shader properties on the image.materialForRendering rather than image.material and it should play nice with all of those things, but you may also need to subclass Image (class MyImage : Image) and do it internally, I can’t quite remember.

Just tried. I can write to materialForRendering without inheriting from Image, and it does change the pattern. But it still changes my original material. I tried Debug.Log(img.materialForRendering) and it is indeed the original material instead of an instance. It’s really weird why there are two different material fileds that point to the same thing.

This behavior is also inconsistent with the sprite renderer’s material field. Afaik materials in sprite renderers are the actual instance