I wanted to use the LWRP in my project which I successfully upgraded to 2019.2.0f1. I follow the documentation on integrating the LWRP into the project and all works well (updating shaders and materials) except for my custom stencil shader. I have to admit I do not understand very well what is happening here - I copied the shader from this source and managed to adjust it so that I can give color values to the shader by code.
What it does
This is the shader in action - the yellow area has a “occluder” material and the circled “occluded” (shader code down below). The effect of part of the circle color changing when entering the yellow area is the effect that I want. In addition when the circle collides with the yellow area I set the target color I want with code on the yellow-area-object.
The Problem
When switching my graphics setting to use LWRP the occluded part (stencil ref 4) gets cut off but the second pass of the occluded shader simply does not trigger. I tried switching the passes around and now the occluded part works but the un-occluded one does not, so it only executes the first pass. I tried for hours and cannot find out why that is. When I remove LWRP from my graphics settings the shader works as intended.
The Code
This is the shader code for the “occluder”:
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Sprites/Occluder"
{
Properties
{
[PerRendererData] _MainTex ( "Sprite Texture", 2D ) = "white" {}
_Color ( "Tint", Color ) = ( 1, 1, 1, 1 )
[MaterialToggle] PixelSnap ( "Pixel snap", Float ) = 0
_AlphaCutoff ( "Alpha Cutoff", Range( 0.01, 1.0 ) ) = 0.1
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "TransparentCutout"
"PreviewType" = "Plane"
"CanUseSpriteAtlas" = "True"
}
Cull Off
Lighting Off
ZWrite Off
Blend One OneMinusSrcAlpha
Pass
{
Stencil
{
Ref 4
Comp Always
Pass Replace
}
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;
fixed _AlphaCutoff;
v2f vert( appdata_t IN )
{
v2f OUT;
OUT.vertex = UnityObjectToClipPos( IN.vertex );
OUT.texcoord = IN.texcoord;
OUT.color = IN.color * _Color;
#ifdef PIXELSNAP_ON
OUT.vertex = UnityPixelSnap( OUT.vertex );
#endif
return OUT;
}
sampler2D _MainTex;
sampler2D _AlphaTex;
fixed4 frag( v2f IN ) : SV_Target
{
fixed4 c = tex2D( _MainTex, IN.texcoord ) * IN.color;
c.rgb *= c.a;
// here we discard pixels below our _AlphaCutoff so the stencil buffer only gets written to
// where there are actual pixels returned. If the occluders are all tight meshes (such as solid rectangles)
// this is not necessary and a non-transparent shader would be a better fit.
//clip( c.a - _AlphaCutoff );
return c;
}
ENDCG
}
}
}
This is the shader coder for the “occluded”:
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Sprites/Occluded"
{
Properties
{
[PerRendererData] _MainTex ( "Sprite Texture", 2D ) = "white" {}
_Color ( "Tint", Color ) = ( 1, 1, 1, 1 )
[MaterialToggle] PixelSnap ( "Pixel snap", Float ) = 0
[PerRendererData] _OccludedColor ( "Occluded Tint", Color ) = ( 0, 0, 0, 0.5 )
}
CGINCLUDE
// shared structs and vert program used in both the vert and frag programs
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;
sampler2D _MainTex;
v2f vert( appdata_t IN )
{
v2f OUT;
OUT.vertex = UnityObjectToClipPos( IN.vertex );
OUT.texcoord = IN.texcoord;
OUT.color = IN.color * _Color;
#ifdef PIXELSNAP_ON
//OUT.vertex = UnityPixelSnap( OUT.vertex );
#endif
return OUT;
}
ENDCG
SubShader
{
Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"PreviewType" = "Plane"
"CanUseSpriteAtlas" = "True"
}
Cull Off
Lighting Off
ZWrite Off
Blend One OneMinusSrcAlpha
Pass
{
Stencil
{
Ref 4
Comp NotEqual
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ PIXELSNAP_ON
#include "UnityCG.cginc"
fixed4 frag( v2f IN ) : SV_Target
{
fixed4 c = tex2D( _MainTex, IN.texcoord ) * IN.color;
c.rgb *= c.a;
return c;
}
ENDCG
}
// occluded pixel pass. Anything rendered here is behind an occluder
Pass
{
Stencil
{
Ref 4
Comp Equal
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ PIXELSNAP_ON
#include "UnityCG.cginc"
fixed4 _OccludedColor;
fixed4 frag( v2f IN ) : SV_Target
{
fixed4 c = tex2D( _MainTex, IN.texcoord );
if (c.r < .5 && c.g < .5 && c.b < .5 ){
return _OccludedColor * c;
} else {
return _OccludedColor * c.a * _OccludedColor.a;
}
}
ENDCG
}
}
}
So I am at a loss right now. I really wanna use shader graph for my project but this stencil shader is very important so I need it to work but I don’t understand why it broke. Thanks for your time.