- Home /
How to use Post Processing Stack with stencil masking shaders
Hi, So I want to create a post processing effect that affects only an area of the screen in one way and have the rest be affected differently. For example have a sphere around the player position render normally and the rest render in black and white. For this I created a shader that writes to the stencil, not really rendering anything, and put the material to a sphere. Properties { [PerRendererData]_MainTex ("Texture", 2D) = "white" {} } SubShader{ Tags{ "RenderType" = "Opaque" "Queue" = "Geometry" } ColorMask 0 ZWrite off Stencil { Ref 120 Comp always Pass replace } Pass { 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;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex;
fixed4 frag (v2f i) : SV_Target
{
return (0,0,0,0);
}
ENDCG
}
}
Then I created a shader that renders normally if the stencil is the same and black and white if it's different. HLSLINCLUDE
#include "Assets/PostProcessing-2/PostProcessing-2/PostProcessing/Shaders/StdLib.hlsl"
TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
float4 FragGrayscale(VaryingsDefault i) : SV_Target
{
float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord);
float luminance = dot(color.rgb, float3(0.2126729, 0.7151522, 0.0721750));
color.rgb = luminance.xxx;
return color;
}
float4 Frag(VaryingsDefault i) : SV_Target
{
float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord);
return color;
}
ENDHLSL
SubShader
{
Cull Off ZWrite Off ZTest Always
Pass
{
Stencil
{
Ref 120
Comp equal
Pass keep
}
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment FragGrayscale
ENDHLSL
}
Pass
{
Stencil
{
Ref 120
Comp equal
Pass keep
}
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment Frag
ENDHLSL
}
}
However the post processing stack seems to simply ignore the stencil part of the pass, I assume because no 'depth' or 'stencil' info is being sent with the source texture, but I don't know how exactly I can access this information. Also the post processing stack only uses one of the shader pass, which I don't know how to change but could call BlitFullscreenTriangle twice, once for each pass if needded. This is the code for the custom effect I have:
public sealed class PossessionAreaFXRenderer : PostProcessEffectRenderer<PossessionAreaFX>
{
public override void Render(PostProcessRenderContext context)
{
var sheet = context.propertySheets.Get(Shader.Find("Hidden/PossessionEffect"));
context.sourceFormat = RenderTextureFormat.Depth;
context.command.BlitFullscreenTriangle(context.source, context.destination, sheet, 0);
}
}
Your answer
Follow this Question
Related Questions
How can I save and load a Coroutine state ? 0 Answers
Post Processing stack - Volume effects have all the fields disabled. 1 Answer
How to manipulate PostProcessing effects settings during execution with c#? 1 Answer
How to change the color of a vignette? 0 Answers
Change Post Process Volume Color Grading at runtime 0 Answers