uGUI mask component

I needed flash like masking, so I’ve made a depth mask shader, but it’s hard to set up and easy to mess up. I saw the new uGUI mask component, and it’s great, but when you move the game object with the mask it doesn’t update. So I was wondering if someone can tell me how the mask component is implemented, or suggest how to change the shader so it’s more flexible. Also I couldn’t get the shader to work with lightning…

1849237–118597–SpriteDepthMask.shader (1.65 KB)

Bump! :frowning:

I think it does not ‘seem’ to update because when you move the mask object you must also be moving the children. Maybe try instead to move the children?

Thank you. I missed that parenting part. But i need the child to stay at the same position. So I made a script to reset the childs position and it works. It would be great to change the mask component to target a transform instead of a child. Thats why i was asking for the source or implementation details.

another way to make it seem as though the child is not moving is parent the/a camera to the child so they both move at same time?

or actually i guess that does not work like i thought never mind

I ran into this same exact problem, and finally got around to setting up a workaround yesterday and today.

To get a sort of “reverse mask” effect (i.e.: masking by children, rather than a parent) I am using the scripts offered here by @mouurusai and @Angry_Water . This uses the same stencil-buffer approach as the regular masks, so there’s no soft masking, but it works pretty darn well! Two points of attention here:

  • Changing the alpha comparison to compare against 0.5 in the Stencil Mask shader produces cleaner, softer edges.
  • Because the StencilDrawInMask shader is drawn after the Transparent queue, all “maskees” will be on the foreground of your scene. I compensate for this using a SetUGUIRenderQueue script (included in the attachments).

I also have a situation where I wanted some smoother results, and for my use-case it was enough to simply offset the texture, essentially using the sprite’s own texture as its mask. For this I wrote a simple MaskByOffset shader that’s super easy to use and set up. It’s a bit specific in the problem it solves, but I’ve included it regardless.

Also note that for both solutions I’ve needed to set up a separate Camera just for the UI layer with Clear Flags set to Depth Only.

Hope this helps you a bit! Good luck!

1854914–118906–SpriteMaskByOffset.shader (1.46 KB)
1854914–118907–SetUGUIRenderQueue.cs (555 Bytes)

1 Like

Thank you. I tested Stencil Mask and Stencil Draw In Mask, it could be what I need. I will need to figure out how to draw mask’s sprite over the whole thing and how to have multiple masks (currently there is only one “hole” that is shared, i need multiple). Using Stencil buffer seems like a better and more robust solution then depth masks. Do you think that the mask component uses it?

I don’t have time to play with this at the moment, so leaving this part be. :wink:

Using the stencil buffer masks you can actually use as many masks as you want! One thing you might want to do for more complex situations is to expose a ref variable to both Materials. That way you can group masks together by using a different reference number for each “group”, so they don’t accidentally intersect or overlap.

Yup! I don’t remember where I saw this, but I’ve seen it confirmed a couple of times. This is also why the Mask component doesn’t handle transparent masking.

Thank you :slight_smile:

Gents,

I have imported the scripts and tried to get this work, I am a bit lost on how to do it. I have no experiece with shaders.

I set SetUGUIRenderQueue.cs on the parent object.

And created a material with your shader in the child object.

When I play the scene nothing seems to happen they just overlay one another.

Am I doing anything wrong?

Regards,
Mark