Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by thehen2 · Sep 08, 2014 at 01:10 PM · 2dshaderspritemask

Sprite masking

Hi all,

Coming from an HTML5 background, 2D masking was very simple:

alt text

In Unity I want to create something similar to the destination-out effect, where a sprite is subtracted from other objects on the sorting layer.

I created the following shader which subtracts from every sorting layer in front of the object, but I just want it to subtract from it's current sorting layer.

 Shader "Custom/MaskTest" {
 
     Properties
     {
         _MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
         _Cutoff ("Base Alpha cutoff", Range (0,.9)) = .5
     }
  
     SubShader {  
         Tags {"Queue" = "Transparent"}
          Offset 0, -1
         ColorMask 0
         ZWrite On
         Pass
         {
             AlphaTest Greater [_Cutoff]      
             SetTexture [_MainTex] {
                 combine texture * primary, texture
             }
         }
     }
 }

Is this the correct approach? Any help would be appreciated.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
5
Best Answer

Answer by Bezzy · Sep 09, 2014 at 01:38 PM

Your shader looks about right.

It's the "Queue" you want to play with. And you'll need another standard sprite shader which draws later than the DepthMask shader. You'll use this for any sprite you want the mask to "block" (as well as place that sprite "behind" the masked area)

Objects you want to show "through" the mask should be on "Queue"="Transparent" The Mask itself should be at "Queue"="Transparent+1" Objects you want to be "blocked" by the mask should be on "Queue" = "Transparent+2"

So, the order of drawing is such:

Firstly, things that aren't affected by the mask at all are drawn to the screen, (when "Queue"="Transparent") Then, the mask is drawn. It occupies depth where your depth texture's alpha value are above "cutoff". (when "Queue"="Transparent+1") Then, the sprites affected by the mask are drawn after. If these sprites are physically occluded (i.e. behind) the mask, then so long as they have a ZTest LEqual on their shader (which happens to be the default if not specified), the mask will block.

What the mask has essentially done is "sealed" or "baked" any existing colours on the screen to its depth. When subsequent things are drawn, later in the queue, they will still have to check against the depth.

I wish this were simpler. I'm so, so sorry.

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image thehen2 · Sep 09, 2014 at 02:40 PM 0
Share

Thanks very much for the reply!

$$anonymous$$oving the mask and the masked object into their own queues makes a lot of sense, but unfortunately I'm struggling to get it to work.

I duplicated the default sprite shader and changed the queue to "Queue"="Transparent+2":

 Shader "Custom/Sprites/Diffuse-$$anonymous$$asked"
 {
     Properties
     {
         [PerRendererData] _$$anonymous$$ainTex ("Sprite Texture", 2D) = "white" {}
         _Color ("Tint", Color) = (1,1,1,1)
         [$$anonymous$$aterialToggle] PixelSnap ("Pixel snap", Float) = 0
     }
 
     SubShader
     {
         Tags
         { 
             "Queue"="Transparent+2" 
             "IgnoreProjector"="True" 
             "RenderType"="Transparent" 
             "PreviewType"="Plane"
             "CanUseSpriteAtlas"="True"
         }
 
         Cull Off
         Lighting Off
         ZWrite Off
         Fog { $$anonymous$$ode Off }
         Blend One One$$anonymous$$inusSrcAlpha
 
         CGPROGRA$$anonymous$$
         #pragma surface surf Lambert vertex:vert
         #pragma multi_compile DU$$anonymous$$$$anonymous$$Y PIXELSNAP_ON
 
         sampler2D _$$anonymous$$ainTex;
         fixed4 _Color;
 
         struct Input
         {
             float2 uv_$$anonymous$$ainTex;
             fixed4 color;
         };
         
         void vert (inout appdata_full v, out Input o)
         {
             #if defined(PIXELSNAP_ON) && !defined(SHADER_API_FLASH)
             v.vertex = UnityPixelSnap (v.vertex);
             #endif
             v.normal = float3(0,0,-1);
             
             UNITY_INITIALIZE_OUTPUT(Input, o);
             o.color = v.color * _Color;
         }
 
         void surf (Input IN, inout SurfaceOutput o)
         {
             fixed4 c = tex2D(_$$anonymous$$ainTex, IN.uv_$$anonymous$$ainTex) * IN.color;
             o.Albedo = c.rgb * c.a;
             o.Alpha = c.a;
         }
         ENDCG
     }
 
 Fallback "Transparent/VertexLit"
 }
 

Then I modified my existing shader to "Queue" = "Transparent+1":

 Shader "Custom/$$anonymous$$askTest" {
 
     Properties
     {
         _$$anonymous$$ainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
         _Cutoff ("Base Alpha cutoff", Range (0,.9)) = .5
     }
  
     SubShader {  
         Tags {"Queue" = "Transparent+1"}
          Offset 0, -1
         Color$$anonymous$$ask 0
         ZWrite On
         Pass
         {
             AlphaTest Greater [_Cutoff]      
             SetTexture [_$$anonymous$$ainTex] {
                 combine texture * primary, texture
             }
         }
     }
 }

Unfortunately this is not having any effect. Looking at it, is "Offset 0, -1" overriding the queue anyway? Without the offset I can't seem to get any masking effect whatsoever though :/

avatar image Bezzy · Sep 09, 2014 at 02:59 PM 0
Share

Hunch: Don't use #pragma surface surf for anything UI releated. There are lots of extra render passes with that system which may well affect the z buffer.

Stick to using for non-lit stuff. #pragma vert vert #pragma frag frag

e.g. http://docs.unity3d.com/$$anonymous$$anual/ShaderTut2.html

Also, yes, Offset directly messes with depth, and gives inconsistent results across different graphics cards, so it's best to avoid it for anything other than fighting z fighting for things that absolutely have to be flat ontop of one another.

avatar image thehen2 · Sep 09, 2014 at 03:02 PM 0
Share

Brilliant, thanks, I got it working :)

avatar image Dmsotir thehen2 · Nov 04, 2016 at 03:17 AM 1
Share

@thehen2 would you be so kind as to share your code for that if you still have it?

avatar image Guidez · Nov 11, 2014 at 01:29 PM 1
Share

thehen2, could you post your fully created solution?

avatar image AllWallsWillFall · Jul 17, 2015 at 05:59 PM 1
Share

Could someone post the final shader code? Shader coding is a little over my head.

avatar image
0

Answer by polinaihoj · Jun 16, 2015 at 05:39 AM

i was wondering what your guys' input might be on my problem that's also to do with masking.

i'm working on a game to teach hand washing to kids where i have two hand shaped sprites with random bits of dirt that get generated on them that then need to be scrubbed off.

my problem is that sometimes the bits of dirt generate and peek out a little outside the bounds of the hands, and it looks sloppy. i want to somehow use masking (although this might not be the right approach) so that any of the bits of dirt that peek out over the boundary of the hand sprites get masked by the canvas, or otherwise don't appear.

any suggestions?

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by SoloSebo · Sep 16, 2015 at 12:31 PM

Not sure if i should have started a new thread. But how can i accomplish SOURCE-IN?

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

28 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Sprite Color Mask 0 Answers

Rewrite simple alphamask fixed function shader to surface or cg shader 2 Answers

Create a shader using mask for sprite 1 Answer

ShaderGraph Position from Texture Sample Issue 0 Answers

"Blend SrcFactor DstFactor, SrcFactorA DstFactorA" Does not work 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges