Using Stencil Buffer in OnRenderImage() and Image Effects

Hi there,

yesterday I have been struggling with this topic for the whole day and I didn’t came to a proper solution.
I read tons of forum posts, some saying it’s possible using Graphics.SetRenderTarget(), some say it’s not possible at all because the stencil buffer gets cleared right before OnRenderImage() gets called.

For those wondering why one would want to use the stencil buffer in OnRenderImage(): If you have access to the stencil buffer in your post processing shaders, you can limit image effects to single layers of your final render.

This thread is my last resort and I hope someone can give me a final answer/solution to this specific issue.

For the sake of completeness this is my OnRenderImage() and Shader Code right now:

void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
      buffer = RenderTexture.GetTemporary(source.width, source.height, 24);
      Graphics.SetRenderTarget(buffer.colorBuffer, source.depthBuffer);
     
      Graphics.Blit(source, buffer, material, 0);
     
      Graphics.Blit(buffer, destination);
    }

void OnPostRender()
    {
      RenderTexture.ReleaseTemporary(mask);
    }
Shader "Hidden/OnionSkinning"
{
    Properties
    {
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }
    SubShader
    {

        CGINCLUDE
        sampler2D _MainTex;
        ENDCG

        Pass
        {
          Cull Off ZWrite Off ZTest Always
            Tags { "RenderType"="Opaque" }
            LOD 200

            Stencil{
                Ref 1
                Comp Equal
            }

            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;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = fixed4(1,1,1,1);
                return col;
            }
            ENDCG
        }
    }
}

This shader code is supposed to return a white color where ref = 1, but it returns nothing at all, because stencil buffer seams to be empty.

I appreciate any kind of help. Thanks in Advance!

Hi @SlimMarten ,
If you need selective post-processing effects in your rendering, it might be good idea to check command buffers. At least there’s some documentation and good examples out there for the standard rendering pipeline. But you could use command buffers to limit rendering to certain areas, but I don’t know what you’re exactly trying to do.

Here’s a good tutorial on command buffers, explains the needed steps pretty clearly:

1 Like