Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[Released] Sprite Mask - masking system for Unity Sprite

Discussion in 'Assets and Asset Store' started by PoL231, Jan 21, 2015.

  1. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Asset Store link | Demo Scene

    If you're looking for masking system for Unity sprites (SpriteRenderer), you just found it!

    Sprite Mask allows you to mask objects of type Sprite (SpriteRenderer). Masking is based on the Stencil buffer, which makes it very "cheap" and versatile. Masking process is done completely by the GPU, so any kind of transformation is allowed both to the sprites and for the mask itself.

    Unity 5 supported!

    Works on Unity Free/Personal (requires Unity 4.6) and Unity Pro!

    Supported mask types:
    * Rectangle
    * Sprite
    * Texture

    Features:
    * Very fast. Each mask "costs" only 1 draw call.
    * Allows to use up to 7 mask levels.
    * Allows to use any shader, which supports the Stencil buffer.
    * Compatible with all platforms: Mobile, PC, Web, etc.
    * Can be created/enabled/disabled at runtime.

    To get masking working you need to enable 24-bit Depth Buffer:
    Player Settigns -> Resolution and Presentation -> Use 24-bit Depth Buffer

    The standard setting allows for up to 3 levels of masking, and at every level up to 32 independent masks. By changing the configuration, one can get e.g. 4 levels and 16 separate masks for each level or even 7 levels and 2 mask per level.

    Testet on Unity 5.0.x, 4.5.x and 4.6.x. Theoretically it could work on Unity 4.3.x.







     
    Last edited: Mar 7, 2015
    Gozdek likes this.
  2. rayfigs

    rayfigs

    Joined:
    Feb 8, 2009
    Posts:
    41
    Hi, I was interested in your kit. How would this be different than ui masks ?

    Many thanks,
    Ray

     
  3. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi Ray,

    The biggest difference between UI Mask and Sprite Mask is that the UI Mask doesn't work on Sprites (SpriteRenderer) and Sprite Mask does :).

    Under the hood they both are based on the same masking technique: using Stencil buffer. This makes masking extremely cheap for the CPU, because it is done completely on the GPU.
     
    Last edited: Jan 25, 2015
  4. vicenterusso

    vicenterusso

    Joined:
    Jan 8, 2013
    Posts:
    130
    What about gradient alpha?
     
  5. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Unfortunately gradient alpha mask is not supported at this moment. Sprite Mask is based on the same technique that is used by the UI Mask (which also does'nt support gradient alpha mask). Maybe in the future I will look for techniques to achieve gradient alpha mask effect.
     
    Last edited: Feb 12, 2015
  6. helloUnityPips

    helloUnityPips

    Joined:
    Oct 18, 2014
    Posts:
    1
    Hi is it possible in invert mask? I need to create a bullet hole effect.
     
  7. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi, I just made a quick experiment and it seems to work. Now I need to test it in more use cases, e.g. multi level masks. I will notify you about the progress/result.

     
    Last edited: Feb 13, 2015
  8. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    You can check how it is working here. It is in beta stage right now. If you interested just send me your Invoice number via private message and I will send you Unity package via email.
     
  9. firebelly

    firebelly

    Joined:
    Apr 22, 2013
    Posts:
    12
    Any way I can check out the inverted one as well? Ideally, my perfect solution is one that handles inverted + alpha. So that I could fade the cutout using the alpha levels.
     
  10. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi, if you purchased the plugin, just send me your Invoice number via private message. Then I would send you the package.

    BTW At this moment, SpriteMask does not support alpha fade, but I will try to achieve that effect by e.g. resigning from multilevels. Alpha fade would be available after changing SpriteMask working mode. But first of all I'll need to find a way to get the fade effect at all.
     
    mkusan and tkml like this.
  11. stevelie

    stevelie

    Joined:
    Feb 6, 2015
    Posts:
    15
    Hi, nice plugin. But i got a problem. the mask work in scene view, but when i tested it on the game view, nothing shows. Same thing happen when using the camera preview, I can't see any masked object on it. Here's what I did, I create an empty gameobject, add a spriteMask on it. set the type into rectangle ( 1x1 ). And then i added a sprite into the mask. Did I miss something?
     
  12. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi, check if the Sprite (SpriteRenderer) is under the mask on the hierarchy. If yes, then try to make maski bigger. Check also if you have turned on the 'Use 24-bit depth buffer'. Let me know if ir's working now.
     
  13. stevelie

    stevelie

    Joined:
    Feb 6, 2015
    Posts:
    15
    yes everything is working now. But I notice one thing, i got this red line border around the mask, can I remove that?
     
  14. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    The red line is Gizmos. It is visible only in the editor. To dismiss it just comment function OnDrawGizmos() in the SpriteMask class. More info: http://docs.unity3d.com/ScriptReference/Gizmos.html
     
  15. Aedous

    Aedous

    Joined:
    Jun 20, 2009
    Posts:
    244
    Hi, nice plugin you have here, bought it because it does what it says on the box. I'm trying to use to get a "feet under water" look for the isometric game I'm working on. It all works perfectly, but unfortunately it doesn't take into account the sorting layers :(. It draws the masked layer on top of all the other layers.

    Is there any way to have it take into account the order in layer and sorting layer, so it doesn't draw on top of everything ? is that something even I can even look into to understand how sorting layers are taken into account ?

    I'm also using Unity 5, and have my mask with a sprite on one sorting layer, and then my other sprites on other sorting layers which are not using the mask material, the mask just appears above all sprites.
     
    Last edited: Mar 9, 2015
  16. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi, in my use cases the sorting was correct. Maybe try to change value of:

    private const int BASE_RENDER_QUEUE = 3000;

    in the SpriteMask class to 2500. Let mi know if this solves your problem. If the problem still exist, then if you send me your scene (or similar) I could help you more.
     
  17. Aedous

    Aedous

    Joined:
    Jun 20, 2009
    Posts:
    244
    Thanks man, setting it to 2500 didn't work, but when I lowered it down to 1500 it seemed to have done the trick. Is there a reason as to why this worked ?
     
  18. Crowye

    Crowye

    Joined:
    Oct 8, 2014
    Posts:
    2
    Hey!
    Any chances that Sprite Mask is/will support masking text meshes and/or text mesh pro object and not only sprites?
    Would be a really nice feature!

    Thank you!
     
  19. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi,
    Masking is done by shader via Stencil buffer. Any kind of object can be masked, provided that the object shader supports Stencil buffer. TextMesh Pro is supported out-of-the-box:

     
  20. Aedous

    Aedous

    Joined:
    Jun 20, 2009
    Posts:
    244
    Hey again!

    I've got it working with showing the masks in the correct sprite order, but now I'm at another point where I have two characters each having their own Sprite Mask GameObject. The problem is having two masks overlapping each other for example:

    I have Object A and Object B, each containing a mask that clips off the bottom half of the sprite. Object A and B each contain one gameobject which is the sprite we want to clip. Problem is when Object A is in front of object B, Object B is fully masked because of Object A.
    It seems to just be an overlapping issue, and which canvas gets to draw first, hides any mask that is behind it.

    I'm also updating the sprite order of each sprite according to their y position, to give it it's own natural sorting order of things.

    I'm also using the Sprite version of your Sprite Mask, and just using a grey image / pixel and scaling it around to fit my needs.

    Thanks for your quick response as well last time! hope you can help me out with this one :(

    Update:
    Just to give you a better idea of what's going on. Use any coloured sprite square as you're mask, add a sprite underneath it. Duplicate it, and make sure the Masks are both on the same sorting layer and the same order in layer. One takes priority over the other.



    I attached an image that will hopefully help, "Mask" and "Mask 2" have the same order in layer, therefore "Mask" cut's into "Mask 2" sprite.
     
    Last edited: Mar 11, 2015
    feoktistov likes this.
  21. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi, the problem is that both mask have the same sorting order. If 'Object A' is masked with 'Mask' and 'Object B' is masked with 'Mask 2', then ensure to set sorting like this:

    Code (CSharp):
    1.  
    2. 'Mask' - order 0
    3.     'Object A' - order 1
    4. 'Mask 2' - order 2
    5.     'Object B' - order 3
    6.  
     
  22. stevelie

    stevelie

    Joined:
    Feb 6, 2015
    Posts:
    15
    Hey,
    Apparently that problem that i got, about the mask working in scene view and not in game view is still exist. I already add the gameobject under the mask, the mask is big enough, and the 24-bit depth buffer is on. I really dont know what went wrong. Weird thing is, i got other mask working fine. It used to have the same problem, but after i restarted unity several times, it went correct by itself. I tried restarting unity too, but this time its no luck.

    one more thing, even the gizmos is not showing on the game view, even after i toggled the gizmos on and off several times. And I'm using rectangle mask, if that helps.

    Maybe you have some ideas?
     
    Last edited: Mar 11, 2015
  23. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    If you have a demo scene ,just send it to me and I'll take a look on it. If not then please send me some screenshots via private message, so I can see whats wrong.
     
  24. stevelie

    stevelie

    Joined:
    Feb 6, 2015
    Posts:
    15
    sent! via conversation
     
  25. Aedous

    Aedous

    Joined:
    Jun 20, 2009
    Posts:
    244
    Thanks for the quick response, but you misunderstood me. In my game because it's isometric, the sorting order of sprites gets updated at run time so that objects can go behind and in front of each other when moving. Isn't there anyway to have two masks on the same order in layer and not have them affect each other ?
     
  26. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    If two mask have the same sorting order, they can overlap with each other, just like in your case. Try to set orders in that way, that the values won't appear twice the same. E.g.:

    Code (CSharp):
    1. Mask 1 -> order: -2
    2.     Object 1 -> order: any number above 0
    3. Mask 2 -> order: -1
    4.     Object 2 -> order: any number above 0
     
  27. Aedous

    Aedous

    Joined:
    Jun 20, 2009
    Posts:
    244
    Thanks but that's not really practical for an isometric game or even a top down game as I'm using the y Position of a sprite to determine the sorting order, and therefore sometimes some sprites will have the same order because they are in the same y Position. The order in layer is not going to be the same all the time, it's only when two sprites happen to just be in same y Position ( not particularly the same x Position ).

    Are you saying that there is no way to have them on the same order in layer ?

    Edit: Also have tried your solution, same results if Mask 1 is on -1, and Mask 2 is on -2, the Objects inside are on the same order in layer it will still overlap ( Mask 1 overlaps Mask 2).
    All I need it to do is not overlap, regardless of what order layer they are on, it should only mask the sprite that is in it's child, isn't that what it's supposed to do ?
     
    Last edited: Mar 11, 2015
  28. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Masking mechanism is quite sensitive for sorting order.

    Check the example below.

    In this example ordering looks like followed:
    Code (CSharp):
    1. Mask 1 -> order: 1
    2.     Animal 1 -> order: 1
    3. Mask 2 -> order: 2
    4.     Animal 2 -> order: 2
    To have it working properly in your case I can only suggest, that you don't use the same sorting order for sprites. You could reserve e.g. 10 order values for one Y value, and if you detect that there are more than one sprite at the same Y value, you can just set next available order value.

    At y=1 you can set orders from 0-10, at y=2, you can set values 10-20, etc.

    That would solve your problem absolutely.
     
  29. Aedous

    Aedous

    Joined:
    Jun 20, 2009
    Posts:
    244
    Hmm I see, thanks for that you may have just solved it, will have to test it out but you've given me a good direction to head in, hopefully it all goes well. Will post the solution here if anybody else has this issue.
     
  30. Aedous

    Aedous

    Joined:
    Jun 20, 2009
    Posts:
    244
    Hello, me again :), Just wanted to know if it was possible to allow the masked sprites be affected by lights ? I've managed to get them running without sharing the same sorting order. I just realised that they are unlit sprites, I tried changing the shader for Mask and Default to include "Lighting On" but doesn't seem to have any effect. Any advise ?
     
  31. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi. You can use any shader, but you have to be sure it supports Stencil buffer. If it doesn't, check the Readme.txt file in the SpriteMask package. Search for: "Can I use my own shader?".
    If you need more help with extending your shader, just let me know and I will help you.
     
  32. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    "SpriteMask/Default" source code is not open source so please remove it from here and send me a private message.
     
    Last edited: Mar 14, 2015
  33. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Aedous, you do not have permission to share other people's code publicly, you can talk about the code, and ask the asset author.
     
  34. Aedous

    Aedous

    Joined:
    Jun 20, 2009
    Posts:
    244
    So sorry about that, was not thinking straight, will send you a PM.
     
  35. Uber6

    Uber6

    Joined:
    Sep 30, 2013
    Posts:
    25
    Hello.
    Would it be possible to use this asset to mask together sprite and spine assets?
     
  36. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi, what do you mean with 'spine assets'? Sprite Mask can mask any object whose shader supports Stencil buffer or whose shader could be extended to use Stencil buffer.
     
  37. Uber6

    Uber6

    Joined:
    Sep 30, 2013
    Posts:
    25
    Spine is a 2D skeletal animation toolset. They do not use typical unity sprite shaders. Can you help me identify if those shaders support Stencil Buffer?
     
  38. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    If you provide me some resources to work with I can check if Sprite Mask can work with them.
     
  39. Uber6

    Uber6

    Joined:
    Sep 30, 2013
    Posts:
    25
  40. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    After extending 'Spine/Skeleton' shader I've got this effect:


    Mask works for mesh itself, but the shadow is not masked at all. Maybe if you are shader master you could get shadow masked too. To get the dragon masked I needed to extend SpriteMask functionality a little bit, so if you interested send me your Invoice number and email via PM and I will send you a custom SpriteMask package.
     
  41. Manny Calavera

    Manny Calavera

    Joined:
    Oct 19, 2011
    Posts:
    205
    I'm also interested in the inverse mask (carving a hole in the sprites behind it) and a few other scenarios.

    A few questions:

    - Does the mask have to be a parent of the affected sprites? Or does it work in a flat hierarchy?
    - Can a Sorting Layer and Sorting Order range be specified? For instance, have the mask affect everything in the 'Enemy' sorting layer between sorting order 0 and 10.
    - Can it be used to apply a decal (Sprite A) on top of a sprite (Sprite B) so that Sprite B works as a mask in such a way that Sprite A is only applied on pixels where Sprite B is not transparent?
     
  42. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    In current release (1.2) mask have to be parent of affected sprite, but I'm currently testing version in which the hierarchy can be flat.

    I've added component 'SkipMasking', which allows you to skip some items from being masking. You just need to add that component to GameObject, and the object itself and his childs will be skipped by the mask.

    Correct me if I'm wrong but you just want to use one sprite to mask another one... Yes this works in since release 1.0. Just select type 'Sprite' on the SpriteMask component and specify masking Sprite.

    As I mentioned earlier, flat hierarchy feature and SkipMasking component are not in current release (1.2), but if you're interested just send me your Invoice number via PM and I will prepare a package for you.
     
    Manny Calavera likes this.
  43. sirio21

    sirio21

    Joined:
    Mar 11, 2013
    Posts:
    114
    hi, it possible to animate the mask (animator with transforms). From a transparent image (masked sprite) move the mask revealing the sprite. And it possible to use several mask with one sprite to do it? Thanks
     
  44. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi sirio21,

    Yes, you can do any kind of animations on transform. What you can't do is to animate the mask alpha channel.

    Yes, it is possible. You can have a mask that consists of many mask elements.

    Take a look at this example: http://truesoft.pl/sprite_mask/blood/

    Click on tree to put blood on them. There is only one SpriteMask, which consists of 4 parts: tree sprites.
     
  45. BusyRobot

    BusyRobot

    Joined:
    Feb 22, 2013
    Posts:
    148
    I looked, but I don't seem to have the "Player Settigns -> Resolution and Presentation -> Use 24-bit Depth Buffer" option? (I'm using a Mac)

    Also, I'm currently creating my own texture by setting the pixels on it and then creating a sprite and setting the renderer like this

    Code (CSharp):
    1. rend2 = gameObject.GetComponent<SpriteRenderer> ();
    2.            
    3.             pixelSprite = new Sprite ();
    4.            
    5.             pixelSprite = Sprite.Create (pixelTexture, new Rect (0, 0, mapSize.x * 4, mapSize.y * 8), new Vector2 (0, 0), 2);
    6.            
    7.             rend2.sprite = pixelSprite;
    Will your masking work with that created texture/sprite?
     
  46. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi Biggerplay,

    It seems that in Unity 5 this option has disappeared, but masking works on my side in Unity 5.

    It doesn't matter if the texture is created at runtime or it comes from assets. So my answer is... yes it will work.
     
  47. BusyRobot

    BusyRobot

    Joined:
    Feb 22, 2013
    Posts:
    148
    I'm actually using Unity 4.6.2f1 but still can't see the option anywhere.
     
  48. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    I'm using Unity 4.6.5f1:

     
  49. BusyRobot

    BusyRobot

    Joined:
    Feb 22, 2013
    Posts:
    148
    Ah, I'm working on a PC/Mac game, not mobile, I don't have that option for the stand alone player.
     
  50. pep_dj

    pep_dj

    Joined:
    Nov 7, 2014
    Posts:
    179
    Hi. I have in my project a game object (sprite) that is a character, and it has a child sprite, that is the shadow. I would like to set transparency globally for both sprites. But if I set transparency for each sprite I get something like this (sorry for the bad artwork):



    Can I use your "Sprite Mask" to achieve this?: