- Home /
Make stencil shader target materials with same int 'ID' ?
Hi I am using a stencil shader as shown here
sorry ,I have no skill in shader scripting.
I am using the shader to cut own holes in sprites but if I have multiple objects in the scen with the same Mask and Masked shader materials on them then objects that should not cut holes into other sprites start doing so.
So how can i set some kind of ID on each material so that the Mask and Masked shader materials only affect those with the same ID ?
This is placed on materials that will do masking (will do the cutting out)
Shader "Custom/Mask"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
[MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent-1"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Cull Off
Lighting Off
ColorMask 0
ZWrite Off
Blend One OneMinusSrcAlpha
Stencil
{
Ref 1
Comp always
Pass replace
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ PIXELSNAP_ON
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
half2 texcoord : TEXCOORD0;
};
fixed4 _Color;
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
OUT.texcoord = IN.texcoord;
OUT.color = IN.color * _Color;
#ifdef PIXELSNAP_ON
OUT.vertex = UnityPixelSnap (OUT.vertex);
#endif
return OUT;
}
sampler2D _MainTex;
fixed4 frag(v2f IN) : SV_Target
{
fixed4 c = tex2D(_MainTex, IN.texcoord) * IN.color;
if (c.a < 0.1) discard;
c.rgb *= c.a;
return c;
}
ENDCG
}
}
}
This is placed on materials which will be masked (will be cut out)
Shader "Custom/Masked"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
[MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Cull Off
Lighting Off
ZWrite Off
Blend One OneMinusSrcAlpha
Stencil
{
Ref 1
Comp notequal
Pass keep
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ PIXELSNAP_ON
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
half2 texcoord : TEXCOORD0;
};
fixed4 _Color;
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
OUT.texcoord = IN.texcoord;
OUT.color = IN.color * _Color;
#ifdef PIXELSNAP_ON
OUT.vertex = UnityPixelSnap (OUT.vertex);
#endif
return OUT;
}
sampler2D _MainTex;
fixed4 frag(v2f IN) : SV_Target
{
fixed4 c = tex2D(_MainTex, IN.texcoord) * IN.color;
c.rgb *= c.a;
return c;
}
ENDCG
}
}
}
Answer by villevli · Sep 07, 2016 at 05:28 PM
Just changing the Ref value could be enough for your game (create a property for it) but if two masks can overlap in the game the following is required:
Add these to your shaders. The Mask Layer is a bitmask for reading and writing to the stencil buffer. (The stencil buffer is 8bit so only 8 layers are possible) Usually the value should be a power of two, e.g. 1, 2, 4, 8,... if you want to mask only one layer. You can set the Mask Layer property in your materials to make masks that mask only a certain layer or many layers. I also added the Mask Mode property to the Masked shader. You can set it to Equal or NotEqual to invert the mask.
Mask shader:
Properties {
_StencilMask ("Mask Layer", Range(0, 255)) = 1
}
Stencil {
Ref 255
WriteMask [_StencilMask]
Comp Always
Pass Replace
}
Masked shader:
Properties {
_StencilMask("Mask Layer", Range(0, 255)) = 1
[Enum(CompareFunction)] _StencilComp("Mask Mode", Int) = 6
}
Stencil{
Ref 255
ReadMask [_StencilMask]
Comp [_StencilComp]
}
You saved me time and even got me to learn a bit of shader script . Very awesome . Thank you very much !
Just wanted to thank you a lot for this. I was struggling a lot with it, and this $$anonymous$$ask Layer was what I was looking for.
Your answer
![](https://koobas.hobune.stream/wayback/20220612092333im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Image effect shader that masks spritelayer 1 Answer
Adapt alpha mask shader to gradual alpha increase with distance to object center 0 Answers
Using an object as a mask for another object (using Spine) 0 Answers
Generating a texture through Graphics.Blit with shadergraph 0 Answers
2d lighting effect 1 Answer