How to mask sprite with more than 1 mask?

I want mask 1 to display the sprite inside the mask and mask 2 to subtract from the result,

here is an image to illustrate what I want to achieve:


however I am finding this hard since sprite renderers only have 2 modes: visible inside mask or visible outside.

I would appreciate if someone had a solution to this problem, thanks in advance!

Make a png of this shape with transparent white area, and opaque red area. Set it as mask.

Place it over the character.

thanks but i cant do that in my case, i needed to use 2 mask

the shapes i posted are a simplification, in truth the 2 masks are complex shapes that change every frame, I need a way that I can interact with 2 sprite mask

or a way that I can use mask 2 to mask mask 1? To create the shape that you showed, but in runtime

I’m not sure that’s possible with the sprite and sprite mask settings out of the box. But you can probably do it with shaders. Have you looked into Shader Graph? It makes it semi-intuitive to write shaders visually, without coding

This thread might have something useful information, maybe:

I thought about this for a while. Indeed you could use shaders for this. See this thread for a good, clear explanation of some of the required details: Shader stencil and Sprite Masks not working together

So the main idea is to replace Unity’s Sprite Mask with custom, own versions of the built-in sprite shader. It’s less complicated than it might seem. Basically you take the sprite shader from Unity sources, and add the stencil functionality. You can find the source code from the download archive:

Then you can render first a base mask and write to the stencil buffer, and after that a mask that cuts out from the base mask. Now you can move the masks independently.

And if you really need some complex mask that changes every frame (and it’s procedural or something like that) you probably have to render it to a RenderTexture, then read by using ReadPixels and store the result to a Texture2D and then make a Sprite out of that Texture2D using Sprite.Create() function. But that ReadPixels is pretty slow so I would definitely try to find better solution (maybe generate the mask procedurally inside the shader(s) if it would fit your use-case.

Here’s a quick test: