I've a very sipmle Unity scene.
It has two objects in it, which is Sprites, and they both use sipmle black boxes as a textures.
Here's two shaders, one should act as a mask, and second as a object, that should be rendered only in pixels, specified by that mask.
Mask shader:
Shader "Unlit/StencilUnlitShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque"
"Queue" = "Geometry" }
Pass
{
//AlphaTest Greater 0.5 //Only render pixels whose alpha is greater than AlphaValue.
Stencil{
Ref 2
Comp Never//Never - never pass the stencil test, Always - always pass the stencil test
Pass Replace //write Ref value into the stencil buufer
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
//if (col.a < 0.9) discard; //discard a pixel if it's transparent and don't draw it into a buffer
return col;
}
ENDCG
}
}
}
Object shader:
Shader "Unlit/GreenUnlitShader"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
}
SubShader
{
Tags{ "RenderType" = "Opaque"
"Queue" = "Geometry+5" //to draw after stencil object
}
Pass
{
//AlphaTest Less 0.5
Stencil{
Ref 1
Comp Less //Always, Less - if ref value is greater then current value in the stencil buffer
Pass Keep
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);//fixed4(0,1,0.5,0.6);
//if (col.a < 0.9) discard;
return col;
}
ENDCG
}
}
}
The problem is, this doesn't seem to work, and object doesn't seems to be rendered at all (why it should in the places where mask have it's pixels)