Any way to set Stencil buffer in Shader Graph?

Hello!

I’d like to render elements of a scene through a limited window.

I was following a dimension portal tutorial to learn how stencil buffers work. However, I don’t see any access to stencil in Shader Graph like there was in Shader Forge.

Is there any way to add the Stencil code section?

Thanks for any help understanding!

5 Likes

Did you find a solution to this? Was trying the same atm :smile:

Try posting about it in the feedback thread:

@Desoxi Actually it motivated me to learn how to write basic shaders, and it was totally worth it. It’s well documented thankfully, with tons of examples online. Wasn’t as difficult as I thought, but my needs were pretty basic.

You can also download the built-in Unity shaders from the archive page. The standard shader looks pretty complex, but it’s there to reverse engineer and tinker with if I ever need to.

It’s worth noting this was after I switched back to the built-in renderer. Writing shaders for LWRP probably has different requirements and less documentation.

Well, I’m in the exact same situation here, trying to use the ShaderGraph for UI.Image objects, and it’s a mess.
My issue is that I’m having a REALLY hard time figuring out how to use the “old” shader language, especially since I need to do some pretty fancy math in some of my shaders…

If you have a good tutrial, that’d be great, but if there is a way to get ShaderGraph to work with UI.Image objects, that’d be much better :wink:

See the thread I linked above. However, right now Shader Graph is not intended for use with UI components and there isn’t any way to get them to work nicely together without converting the Shader Graph to a vertex fragment shader and modifying it by hand.

Is this still a feature that is missing from ShaderGraph? It would be nice to have access to the stencil buffer values (for reading and writing) if possible.

4 Likes

Yes it is still missing and it’s surprising that a tool written this long ago doesn’t have this basic support.

3 Likes

Well … for this I click “View Generated Shader” and add the stencil settings and save the shader inside the Assets folder

This method sucks, I know

So can you read the stencil buffer yet in Shader graph? Even in a custom function?!

To be fair: it’s possible to read stencil buffer in Shader Graph, but only when creating Fullscreen shader type for some post processing effects.

About writing to stencil buffer: it’s possible to create custom ScriptableRenderPass and within Execute() take advantage of ScriptableRenderContext.DrawRenderers method that takes RenderStateBlock as one of its parameters. It’s cumbersome (works best with RenderingLayerMasks used on renderers that should write to stencil buffer, may result in separate draw calls, etc), but it works.

Here’s an example of how I set it up in custom ScriptableRendererFeature during render pass initialization…

var stencilState = StencilState.defaultValue;
stencilState.enabled = true;
stencilState.SetCompareFunction(CompareFunction.Always);
stencilState.SetPassOperation(StencilOp.Replace);
    
var renderStateBlock = new RenderStateBlock(RenderStateMask.Stencil)
{
    stencilReference = 1,
    stencilState = stencilState
};

… and then use it in custom ScriptableRenderPass

private const int WriteStencilRenderingLayerMask = 2;

public WriteStencilBufferPass(RenderStateBlock renderStateBlock)
{
    _filteringSettings = new FilteringSettings(renderingLayerMask: WriteStencilRenderingLayerMask);
    _renderStateBlock = renderStateBlock;
}

public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
    var drawingSettings = RenderingUtils.CreateDrawingSettings(_shaderTags, ref renderingData, SortingCriteria.CommonOpaque);

    context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref _filteringSettings, ref _renderStateBlock);
}

Fun fact: even though it works we don’t use it anyway and opt for HLSL when needed. Just wanted to share what I’ve found out during Built In - URP transition for our project, perhaps it’ll be useful for somebody.