I have a custom shader I am trying to use on a UI Image element. When the element is rendered by itself, the shader works fine. If I make the UI Image a child of an object with a mask, the shader ceases to update unless I disable and reenable it again.
I have found this problem also happens with the default UI shader as well.
I am using Unity 5.2.3f1.
Here is an example of what’s happening:
The top row of images use my custom shader with an animated value.
The bottom row is using Unity’s default UI shader with an animated color element.
The left column shows unmasked elements.
The right column shows the same objects placed inside an element with a mask script on it.
Using “SetMateralDirty()” or “SetAllDirty()” on any of the masking elements on the right does not change the problem.
Has anyone encountered this problem before? I’ve tried looking around but haven’t found a solution. I’ve attached a copy of the project shown above to help anyone who might want to have a peek.
In diagnosing a bug in my project today, I’ve discovered I’m running into this exact same issue. I’m still on 5.2.2f1 on my end, but I was not experiencing the issue prior to that version (the relevant shader and MonoBehavior in question in my case I originally authored in August, so I’m guessing that’s 5.1.x timeframe).
EDIT: just double-checked, and yep everything works fine if I disable the UI mask component outright. Altering the “Show Mask Graphic” field (enabled in my original implementation) does not resolve the issue, however.
So guessing here but pretty sure the issue is due to us copying the shader and making modifications to support stencils. My guess is that the material that you are referencing for the animation is not the one that is being used to draw (using the original vs the copied).
Okay, so it looks like Phil is correct. The reference is being broken in some way that I’m not very clear on. I did some poking around and found the SetGlobalFloat(string propertyName, float value).
By making the animated value in my shader private, I can then animate it as follows:
I only have one object on screen that needs to be animated, so this solution works for me, but it’s certainly not a workable solution of you need independent animations for multiple objects on screen.
Phil-Unity had it right but didn’t elaborate enough to keep you from just hacking around with the global parameters.
The Mask object causes a modified material to be rendered rather than the baseMaterial so it is no longer rendering the texture that you are updating with the “material” property. Using set on the materialForRendering property will set the correct material if a mask is involved.
I have encountered the problem now as well. But .materialForRendering does not work in my case, since I need to change the properties while the mask is disabled and enable the mask later. Use .material or .materialForRendering does not make a difference, since .materialForRendering points to two different materials, the original and the stenciled copy, depending on the state the mask is in, and the copy is not updated when the original is edited.
I filed a bug-report (case 994413) in the hopes that this behaviour might be fixed in a future release.
Incase anyone’s looking for a solution- After setting the material’s property, simply disable and enable the graphic component in two lines : img.enabled = false; and then img.enabled = true;
I have a ‘solution’, but I don’t know if it is better. I dug a bit in Unity’s open source CS Reference and made a small edit to MaskableGraphic.cs and built a custom dll. Sadly you cannot replace Unity Engine dlls in your Project, you have to replace them in the installation Folder.
Thanks for this thread.
In my project, I had the same issue, a material with a custom shader not updating when changing the value through code. After updating the value, I found that disabling / enabling the gameobject worked, but I also found this line of code that looks more elegant imo:MaskUtilities.NotifyStencilStateChanged(_maskReference);
I have the same problem. Adding stencil support to a simple shader, results in the material not being editable in the inspector window… all the shader variables/properties become greyed out in inspector, and non-interactable.
The shader works just fine, but you have to edit the material separately, not on the game-object it is assigned to.