Stencil buffer issue since urp 12

Hello,

I wrote an outline shader for urp 11.0, with the help of this awesome blog post : The Quest for Very Wide Outlines. An Exploration of GPU Silhouette… | by Ben Golus | Medium

Here is my test scene for the blur and outline shader in urp 11:

This is the exact same scene in urp 12 and 13:

Without entering into detail, the stencil buffer is used to hide the inside of an outline object. So, in this screenshot stencil buffer seams broken (not used).
I also tested to add a CustomRenderObjects that writes to the stencil buffer to completely hide the shader, but this also didn’t work.

By looking to the frame debugger, I saw that now the shader pass write the stencil buffer inside _CameraColorAttachment, instead of the classic _CameraColorTexture like before.
With further re-search, I found that unity is now using two render textures instead of one (_CameraColorAttachment and _CameraDepthAttachment).

That raise some questions:
Should I use _CameraDepthAttachment render texture as stencil buffer texture now?
What is the correct way to use _CameraColorAttachment and _CameraDepthAttachment in a ScriptableRenderPass?
Is there a third texture for the stencil buffer, since urp 12.0?

Edit: The pass is configured like this:

            ColorMask 0
            Cull Back
            ZWrite On
            ZTest Greater
       
            Stencil {
                Ref 1
                Comp Always
                Pass Keep
                ZFail Replace
            }

The pass is invoked like this from a scriptablerender pass

cmd.DrawRenderer(rs.Renderer, outlineMat, j, interiorStencil);


I did a quick test to see if the stencil buffer was still working in urp 12, and apparently everything look good.
Left red part is behind a plane writing 1 in stencil buffer, and right part is behing another one writing 2 inside the stencil buffer.

7623220--948130--upload_2021-11-2_16-12-59.png

So, apparently stencil buffer is still working properly.

I think that the shader pass is writing inside the stencil but doesn’t read it on the final pass of the shader.
Here is how I write inside the stencil buffer from a custom ScriptableRenderPass :

public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
    base.OnCameraSetup(cmd, ref renderingData);

    _target = renderingData.cameraData.renderer.cameraColorTarget;
    _depth = renderingData.cameraData.renderer.cameraDepthTarget;
}

//Later inside the execute
cmd.SetRenderTarget(_target, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store,
                            _depth, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store);
for (var j = 0; j < subMeshCount; j++)
{ 
    cmd.DrawRenderer(rs.Renderer, outlineMat, j, interiorStencil);
}

Here is how I should read the stencil buffer :

cmd.SetRenderTarget(_target, _depth);
cmd.Blit(_nearestPointID, _target, outlineMat, SHADER_PASS_JFA_OUTLINE);

Shader stencil configuration look like this:

Pass // 1 (Pass to write)
{
    Name "INNERSTENCIL_DEPTH"

   ColorMask 0
   Cull Back
   ZWrite On
   ZTest Greater
           
   Stencil {
      Ref 1
      Comp Equal
      Pass Keep
      ZFail Replace
   }
   ...
}

Pass // 5 (Pass to read)
{
   Name "JUMPFLOODOUTLINE"

   Stencil {
      Ref 1
      Comp NotEqual
      Pass Zero
      Fail Zero
   }
   ...
}

I think, I’m missing something inside the ScriptableRenderPass but I have no clue.
I can share the ScriptableRenderPass script if needed.

Hello,

Since I did not succeed to use the stencil buffer, I created a tempory texture to hide the center of my outline.
So, everything is back to normal visualy, but without the help of the stencil buffer :confused:

These questions are still in my head, but at least I can move forward (but I hate when I can’t understand something):

Should I use _CameraDepthAttachment render texture as stencil buffer texture, or _CameraColorAttachment is ok?
What is the correct way to use _CameraColorAttachment and _CameraDepthAttachment in a ScriptableRenderPass?
Is there a third texture for the stencil buffer, since urp 12.0?
Does Blit support stencil buffer?
Should I use ScriptableRenderContext.DrawRenderers instead of CommandBuffer.DrawRender for the mesh I want to draw?

Hi, I found solution for this problem. The difference is in using BuiltinRenderTextureType.CurrentActive enum instead of actual camera renderTarget.

// jfa decode & outline render
var cameraColorTarget = renderingData.cameraData.renderer.cameraColorTarget;
var cameraDepthTarget = renderingData.cameraData.renderer.cameraDepthTarget;

cmd.SetRenderTarget(cameraColorTarget, cameraDepthTarget);
cmd.Blit(_nearestPointID,BuiltinRenderTextureType.CurrentActive, _outlineMaterial, SHADER_PASS_JFA_OUTLINE);