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

Sprite Masking with and without Stencil

Discussion in 'Shaders' started by xtimus, Jul 17, 2017.

  1. xtimus

    xtimus

    Joined:
    Jun 16, 2014
    Posts:
    11
    I am trying to mask a sprite with a mask. It works if it is the only game object on screen, but if I create multiple copies of the same game object it doesn't work if they overlap. Do I need a unique stencil ID for each game object? If so how do I set stencil ref through script? It also only lets me set 0-255. This should be fine but what if I have more than 255 unique refs?

    So far I know of 2 ways to achieve sprite masking:
    1. Use stencil in shader but this requires having 2 separate sprite gameobjects (1 for mask, 1 for portrait)
    2. Use a mesh that is shaped for the desired sprite and then use UV map to cutoff the unwanted areas.
    Are there any other methods for sprite masking?

    I am not upgrading Unity to 2017 as it is a subscription model and I want to keep perpetual Unity.

    This is the issue:


    Notice square.

    Here is the code:

    SpriteMask
    Code (CSharp):
    1. // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
    2.  
    3. Shader "Custom/SpriteMask" {
    4.     Properties {
    5.         [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
    6.         _Color("Tint", Color) = (1,1,1,1)
    7.         [MaterialToggle] PixelSnap("Pixel snap", Float) = 0
    8.         [HideInInspector] _RendererColor("RendererColor", Color) = (1,1,1,1)
    9.         [HideInInspector] _Flip("Flip", Vector) = (1,1,1,1)
    10.         [PerRendererData] _AlphaTex("External Alpha", 2D) = "white" {}
    11.         [PerRendererData] _EnableExternalAlpha("Enable External Alpha", Float) = 0
    12.     }
    13.     SubShader {
    14.         Pass {
    15.             ZWrite Off
    16.             Stencil {
    17.                 Ref 1
    18.             Comp always
    19.             Pass replace
    20.             }
    21.         }
    22.     }
    23. }
    SpritePortrait
    Code (CSharp):
    1. // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
    2.  
    3. Shader "Custom/SpritePortrait" {
    4.     Properties {
    5.         [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
    6.         _Color("Tint", Color) = (1,1,1,1)
    7.         [MaterialToggle] PixelSnap("Pixel snap", Float) = 0
    8.         [HideInInspector] _RendererColor("RendererColor", Color) = (1,1,1,1)
    9.         [HideInInspector] _Flip("Flip", Vector) = (1,1,1,1)
    10.         [PerRendererData] _AlphaTex("External Alpha", 2D) = "white" {}
    11.         [PerRendererData] _EnableExternalAlpha("Enable External Alpha", Float) = 0
    12.     }
    13.  
    14.     SubShader {
    15.         Tags {
    16.             "Queue" = "Transparent"
    17.             "IgnoreProjector" = "True"
    18.             "RenderType" = "Transparent"
    19.             "PreviewType" = "Plane"
    20.             "CanUseSpriteAtlas" = "True"
    21.         }
    22.  
    23.         Cull Off
    24.         Lighting Off
    25.         ZWrite Off
    26.         Blend One OneMinusSrcAlpha
    27.  
    28.         Pass {
    29.             Stencil {
    30.                 Ref 1
    31.                 Comp Equal
    32.             }
    33.             CGPROGRAM
    34.             #pragma vertex SpriteVert
    35.             #pragma fragment SpriteFrag
    36.             #pragma target 2.0
    37.             #pragma multi_compile_instancing
    38.             #pragma multi_compile _ PIXELSNAP_ON
    39.             #pragma multi_compile _ ETC1_EXTERNAL_ALPHA
    40.             #include "UnitySprites.cginc"
    41.             ENDCG
    42.         }
    43.     }
    44. }
     
  2. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    Actually, the limit would be 8. The stencil buffer works like a binary mask, so you can only use the values 1, 2, 4, 8, 16, 32, 64 and 128.
     
  3. mmonly

    mmonly

    Joined:
    Mar 25, 2015
    Posts:
    8
    thanks you so much I'm looking for this all day long.