Blit Pass not working on URP and Unity +2021 versions (it does in older ones)

Hello i have been having ome troubles with porting the Sobel Filter shader to SingleInstanced for VR
I actually got it working but only in 2020.1.0f1

im currently on 2021.1.5f1
And seems that the shader or the pass is not longer working on SingleInstanced rendering

It seems like this currently:
Left eye: Gray
Right Eye: Black

Im not sure what is the cause of the problem, but i have reduced the Sobel Filter script to just a testing Color Inversion postprocessing shader to test, and it doesnt work, if someone knows about this it would be pretty nice to know what the problem is and how to solve it

i will attach here the current color inversion filter and the Blit Pass

Im sure-ish this is some kind of deprecation or something new should be used instead

Mi goal at all is to have a working Fade system that doesnt depends of the postprocessing stacks
and it paints all the screen, also i wanted to avoid using meshesh arround the player head, so i wanted to make like a way to multiply the final screen processed color in order to do a decent VR fade out platform agnostic

The filter:

Shader "Unlit/ScreenFadeSinglePass"
{
    Properties
    {
        [HideInInspector] _MainTex("Base (RGB)", 2D) = "white" {}
    }
        SubShader
        {
            Tags { "RenderType" = "Opaque" }
            LOD 200

            Pass
            {
                HLSLPROGRAM
                #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
                #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"

                #pragma prefer_hlslcc gles
                #pragma exclude_renderers d3d11_9x
                #pragma target 2.0


                TEXTURE2D_X(_MainTex);
                SAMPLER(sampler_MainTex);

                float _Delta;
                half4 _MainTex_ST;

                struct Attributes
                {
                    float4 positionOS       : POSITION;
                    float2 uv               : TEXCOORD0;
                    UNITY_VERTEX_INPUT_INSTANCE_ID //insert
                };

                struct Varyings
                {
                    float2 uv        : TEXCOORD0;
                    float4 vertex : SV_POSITION;
                    UNITY_VERTEX_OUTPUT_STEREO //insert
                };

                float2 UnityStereoScreenSpaceUVAdjust(float2 uv, float4 scaleAndOffset)
                {
                    return uv.xy * scaleAndOffset.xy + scaleAndOffset.zw;
                }

                Varyings vert(Attributes input)
                {
                    Varyings o = (Varyings)0;

                    UNITY_SETUP_INSTANCE_ID(input);
                    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

                    VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
                    o.vertex = vertexInput.positionCS;
                    o.uv = input.uv;

                    return o;
                }

                half4 frag(Varyings i) : SV_Target
                {
                    UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);

                    float2 uv = UnityStereoTransformScreenSpaceTex(i.uv);
                    //float2 uv = UnityStereoScreenSpaceUVAdjust(i.uv, _MainTex_ST);

                    half4 col = SAMPLE_TEXTURE2D_X(_MainTex, sampler_MainTex, uv);

                    return 1-col;
                }

                #pragma vertex vert
                #pragma fragment frag

                ENDHLSL
            }
        }
        FallBack "Diffuse"
}

The Blit pass:

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
// this was used on https://gamedevbill.com, but originally taken from https://cyangamedev.wordpress.com/2020/06/22/urp-post-processing/
// Saved in Blit.cs
public class Blit : ScriptableRendererFeature
{

    public class BlitPass : ScriptableRenderPass
    {
        public enum RenderTarget
        {
            Color,
            RenderTexture,
        }

        public Material blitMaterial = null;
        public int blitShaderPassIndex = 0;
        public FilterMode filterMode { get; set; }

        private RenderTargetIdentifier source { get; set; }
        private RenderTargetHandle destination { get; set; }

        RenderTargetHandle m_TemporaryColorTexture;
        string m_ProfilerTag;

        public BlitPass(RenderPassEvent renderPassEvent, Material blitMaterial, int blitShaderPassIndex, string tag)
        {
            this.renderPassEvent = renderPassEvent;
            this.blitMaterial = blitMaterial;
            this.blitShaderPassIndex = blitShaderPassIndex;
            m_ProfilerTag = tag;
            m_TemporaryColorTexture.Init("_TemporaryColorTexture");
        }

        public void Setup(RenderTargetIdentifier source, RenderTargetHandle destination)
        {
            this.source = source;
            this.destination = destination;
        }

        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
            CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag);

            RenderTextureDescriptor opaqueDesc = renderingData.cameraData.cameraTargetDescriptor;

            opaqueDesc.depthBufferBits = 0;

            if (destination == RenderTargetHandle.CameraTarget)
            {
                cmd.GetTemporaryRT(m_TemporaryColorTexture.id, opaqueDesc, filterMode);

                cmd.Blit(source, m_TemporaryColorTexture.Identifier());
                cmd.Blit(m_TemporaryColorTexture.Identifier(), source, blitMaterial);
            }
            else
            {
                Blit(cmd, source, destination.Identifier(), blitMaterial, blitShaderPassIndex);
            }

            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }

        public override void FrameCleanup(CommandBuffer cmd)
        {
            if (destination == RenderTargetHandle.CameraTarget)
                cmd.ReleaseTemporaryRT(m_TemporaryColorTexture.id);
        }
    }

    [System.Serializable]
    public class BlitSettings
    {
        public RenderPassEvent Event = RenderPassEvent.AfterRenderingOpaques;

        public Material blitMaterial = null;
        public int blitMaterialPassIndex = 0;
        public Target destination = Target.Color;
        public string textureId = "_BlitPassTexture";
    }

    public enum Target
    {
        Color,
        Texture
    }

    public BlitSettings settings = new BlitSettings();
    RenderTargetHandle m_RenderTextureHandle;

    BlitPass blitPass;

    public override void Create()
    {
        var passIndex = settings.blitMaterial != null ? settings.blitMaterial.passCount - 1 : 1;
        settings.blitMaterialPassIndex = Mathf.Clamp(settings.blitMaterialPassIndex, -1, passIndex);
        blitPass = new BlitPass(settings.Event, settings.blitMaterial, settings.blitMaterialPassIndex, name);
        m_RenderTextureHandle.Init(settings.textureId);
    }

    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        var src = renderer.cameraColorTarget;
        var dest = (settings.destination == Target.Color) ? RenderTargetHandle.CameraTarget : m_RenderTextureHandle;

        if (settings.blitMaterial == null)
        {
            Debug.LogWarningFormat("Missing Blit Material. {0} blit pass will not execute. Check for missing reference in the assigned renderer.", GetType().Name);
            return;
        }

        blitPass.Setup(src, dest);
        renderer.EnqueuePass(blitPass);
    }
}

Bumping this post! for visibility

Single-pass instanced rendering changed wildly since Unity 2020.2/URP10. You could save yourself the trouble and include the Shaders/Utils/Fullscreen.hlsl library then use the FullscreenVert vertex function instead.

Basically recreating the built-in Blit shader, but with a custom fragment function https://github.com/Unity-Technologies/Graphics/blob/master/com.unity.render-pipelines.universal/Shaders/Utils/Blit.shader

1 Like

Hey thanks for answering, i set that shader but it also doesnt work with 2 eyes, is like something is wrong with the blitz pass, or how should i use this shader in order to make it work?

I still needing a bit of help over here, this shader stills not working , not sure if it has something to do with the forward passes, but i dont know how to use this shader to make it work, any help?

¡

I got this, but I don’t know why there is only half screen is affected by the shader, this is super weird

I’m not sure what more should I do

the only thing I want to do is a Sobel filter for single-pass instanced rendering
i have used cmd.DrawMesh in the pass feature


I dont get it working get, currently testing in Unity 2020.3.15f2
Please could someone help me with this?


I dont know why they touched how the passes or instanced rendering works

Since Blit is broken since URP 10 i have to try doing it with the method i have been told up, but al i get working is this,
i dont get whats wrong could someone give me sources on this?

Bumping this thread

See this Example: How to create a full screen blitting feature under Single Pass Instanced rendering in XR (from [URP] [Doc] Add XR SPI full screen blitting example by thomas-zeng · Pull Request #5395 · Unity-Technologies/Graphics · GitHub)

I also have bit more extensive example here, if you look at this repo, do check the commits as there you can see the diff between the old approach.

1 Like

Doesn’t work with 2021.1.12f1, URP 11.0.0
Only one eye is drawed, and it’s distroted :C

Is the new Blitter function rendering a single triangle ?

Blitter.BlitTexture one seems to return uint vertexID : SV_VertexID;

only with 0, 1 and 2 values

Thanks