Shader Graph and UI Mask

Is it currently so that for the UI Shaders to “respect” UI Masks, use of stencil buffers is needed? In other words this is currently not supported in Shader Graph?

I would like to know this too.
Is it somehow possible to create/use a Shader for Images(UI’s) with Mask?

An answer would be Great!

Also would like to know this.

The way to do this currently is described in this video:

The general workflow is you need to export your final unlit master node to shader code.

From there you need to add the following:

Properties

_Stencil("Stencil ID", Float) = 0
_StencilComp("StencilComp", Float) = 8
_StencilOp("StencilOp", Float) = 0
_StencilReadMask("StencilReadMask", Float) = 255
_StencilWriteMask("StencilWriteMask", Float) = 255
_ColorMask("ColorMask", Float) = 15

Pass

ZTest [unity_GUIZTestMode]

...

Stencil{
    Ref [_Stencil]
    Comp [_StencilComp]
    Pass [_StencilOp]
    ReadMask [_StencilReadMask]
    WriteMask [_StencilWriteMask]
}
ColorMask [_ColorMask]

After doing so, reassign your material to this newly build scripted unlit shader and it should work with UIMask for UGUI

I hade some problems making this work for me. NOTE: This would’nt work with a Rect2DMask! You need to use Mask for it to work on Unity 2019.3.15f1.

Thx it works for me.
It would have been great if Unity make an awesome checkbox in shader graph that made this little change automatic to have better iteration work.

It is even better when they finally start UI integration. It seems like it is planned but will probably take a long while.
https://portal.productboard.com/unity/1-unity-platform-rendering-visual-effects/tabs/7-shader-graph

In case this helps anyone else, followed these steps and manually added the above code into the code shader graph generated and it still didn’t work for me. I eventually found that the code generated by shader graph had 2 places where it defined SubShaders. If this solution doesn’t work for you the first time be sure to look through the generated code and copy the above stencil code into the other subheader sections too.

Thanks, ItsNotAGoodTime, using the second SubShader helps but now the masked image appears inside the bounding box of the mask image, ignoring the mask’s transparent areas.

This is working perfectly in editor. But when my game is built to android, the material simply doesn’t get rendered at all. I searched and found that it could be an issue between stencil and either URP or android device in general, I could’ve understood it wrongly tho. Anyone encountered the same issue and found the solution to this? Thanks in advance!

I’ve attempted several tricks like:

#1 - Using stencil override in the render pipeline setting (layer mask method). This method doesn’t work for UGUI components.

#2 - Moving the stencil portions (in the copied shader script) before the each “Pass” section. This method doesn’t fix it neither.

I’ll keep updating this post for each of my fix attempt. Hopefully I can find the one that works.

EDIT:

So I found the actual cause & the solution, it was rather silly. The problem was actually Unity for some reason decides not to include my custom shaders into the build. The solution is of course adding all of the corresponding shaders to the project setting menu > always included shader list

Can we please get an official solution for that. So we dont have to change stuff in the shader code but can handle it via shadergraph?

Like I mentioned, Unity has it on the Shader Graph roadmap “under consideration”. Though it has been there now for almost 2 years. So they don’t seem to really pay attention to it sadly.
UI Toolkit has it on the roadmap as well under “planned”.

[https://portal.productboard.com/8ufdwj59ehtmsvxenjumxo82/c/50-ui-integration-with-shader-graph

](https://portal.productboard.com/8ufdwj59ehtmsvxenjumxo82/c/50-ui-integration-with-shader-graph)
Found it is the very last point under “Under Consideration”…
I “upvoted it” please if someone else is interested upvote!

I created a custom UI shader so I could recreate Window’s spotlight-like nearby-hover behaviour but I was facing problems with it not being maskable. This thread helped me get a looong way solving it but I still had some issues to work through. I’ll describe what happened and what I did to make it work here for documentation purposes. Maybe someone is facing a similar issue.

My custom shader has a float4 input called _MousePos where, every frame, I update it with the current mouse screen position. It uses this position to calculate the alpha of all Images that uses the material, changing the alpha so only those near the mouse becomes visible.

The problem with this solution is that, when you set “Maskable” to true on a given component, Unity DOES NOT use the material that you created. It uses a internal copy with different values to the variables that we create doing workaround described in this thread. Since the copy is internal, every time my code tries to change _MousePos value, it access only the public one. The observed effect of this is that all Images with Maskable set to false works fine, the spotlight position follows the mouse correctly. But also, all images with Maskable set to true, the spotlight position is never updated.

My solution was to create two materials, one where the masking would never occur and another one where the masking would always occur, ignoring the Maskable setting on the component.
In my scene, ALL image components that use this material have maskable set to false. If I want them to be maskable, I DO NOT set it to true, instead I swap the material to the forced masking one. This way, every component is actually using the material created, instead of a internal copy. Allowing me to keep _MousePos updated.

Following are the material settings to force a material to always be masked even if maskable is to to false on the component.

Stencil ID: 1
Stencil Comp: 3
Stencil Op: 0
Stencil Read Mask: 1
Stencil Write Mask: 0
Color Mask: 15

For the Always Non-Maskable material I simply set its shader to be the original shadergraph.

This worked like a charm for me <3
Thank you

Thanks a lot, you really saved me!! (I was happy when it finally worked)

CRITICAL!

Found more “Pass” methods, and more “ZTest” calls.

Still, after 3 years this hasn’t been fixed.
And thx a lot, spent 5 hours trying to fix it but this saved my life.

For anyone struggling with the newer versions you have to do this
* Important * Dont use the code when you click “View generated code” or “Compile and show code” this will not work and as an other person said earlier remember only masks work not rect masks

Bump this old thread. Ive been trying to convert my Shader Graph shader which changes the skin colour of my sprites into a regular shader to use it in my UI so that I can use masks with it (as it seems impossible with shader graph still). I’ve added all the above code to my shader, but it has a massive section with HLSLPROGRAM code below (from the Shader Graph) and I believe thats messing up the masking somewhere.

I can’t use a 2D Rect Mask or a regular mask (although the mask component looks so bare? nothing there) while using this material. Its weird because regular UI/Unlit/Transparent works fine in terms of masking it, but doesn’t have my skin colour changing effect of course. Its something with the HLSLPROGRAMbit but I’m clueless with shaders.

Here is my shader code: Shader "Unlit/SkinUI"{ Properties { [PerRendererData] _Main - Pastebin.com