Search Unity

Question Dither Post process with weird behavior - Command.Blit - URP (12.1.4) & Unity 2021.2.13f1

Discussion in 'Universal Render Pipeline' started by kev42100, Mar 8, 2023.

  1. kev42100

    kev42100

    Joined:
    Apr 17, 2010
    Posts:
    61
    Hello dear community,

    In my game, I apply a custom SRP post process with a Dither effect.
    GameObjects with a specific layer are rendered to a Render Texture by a camera which outputs to a RT.
    Setup:
    MainCamera with PostProcess enabled. Priority -1
    RenderTextureCamera, PostProcess disabled. Priority 0

    I created a similar script following this tutorial:


    I use ShaderGraph. And when I move the camera, the parts of the screen with the dither effect are not cleared, or take some time to be cleared.
    The shader itself seems quite unstable, when I use a Step node for example, it kind of breaks the rendering.

    An Unity programmer explains on this post that the Blit function is not very advisable to be used.
    Does anyone has tried the static method Blitter.BlitCameraTexture ?


    Code (CSharp):
    1. public class DitherFeature : ScriptableRendererFeature
    2. {
    3.     [SerializeField] private Shader DitherShader;
    4.  
    5.     private DitherPass ditherPass;
    6.  
    7.     public override void Create()
    8.     {
    9.         ditherPass = new DitherPass(DitherShader);
    10.     }
    11.  
    12.     public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    13.     {
    14.         ditherPass.ConfigureInput(ScriptableRenderPassInput.Color);
    15.         renderer.EnqueuePass(ditherPass);
    16.     }  
    17.  
    18.     class DitherPass : ScriptableRenderPass
    19.     {
    20.         public int ditherId = Shader.PropertyToID("_Temp");
    21.        
    22.         private Material ditherMaterial;
    23.         private RenderTargetIdentifier src, dest;
    24.  
    25.         public DitherPass(Shader ditherShader)
    26.         {
    27.             if (!ditherMaterial)
    28.                 ditherMaterial = new Material(ditherShader);
    29.  
    30.             renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;                                
    31.         }
    32.  
    33.         public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
    34.         {
    35.             src = renderingData.cameraData.renderer.cameraColorTarget;
    36.  
    37.             RenderTextureDescriptor desc = renderingData.cameraData.cameraTargetDescriptor;
    38.             desc.depthBufferBits = 0;
    39.  
    40.             cmd.GetTemporaryRT(ditherId, desc, FilterMode.Bilinear);
    41.             dest = new RenderTargetIdentifier(ditherId);
    42.         }
    43.  
    44.         public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    45.         {
    46.             if (ditherMaterial == null)
    47.                 return;
    48.          
    49.  
    50. #if UNITY_EDITOR
    51.             ref var cameraData = ref renderingData.cameraData;
    52.             if (cameraData.cameraType == CameraType.SceneView) return;
    53.             if (cameraData.cameraType == CameraType.Game) cameraData.clearDepth = true;
    54. #endif
    55.      
    56.             CommandBuffer cmd = CommandBufferPool.Get("DitherFeature");
    57.             VolumeStack volumes = VolumeManager.instance.stack;
    58.             DitherPostProcess ditherPP = volumes.GetComponent<DitherPostProcess>();
    59.  
    60.             if (ditherPP.IsActive())
    61.             {
    62.                 ditherMaterial.SetFloat("_RenderTextureOpacity", ditherPP.RenderTextureOpacity.value);
    63.                 ditherMaterial.SetFloat("_DitherSize", ditherPP.DitherSize.value);
    64.  
    65.                 Blit(cmd, src, dest, ditherMaterial, 0);
    66.                 Blit(cmd, dest, src);
    67.  
    68.                 context.ExecuteCommandBuffer(cmd);
    69.                 cmd.Clear();
    70.                 CommandBufferPool.Release(cmd);
    71.             }
    72.         }
    73.  
    74.         public override void OnCameraCleanup(CommandBuffer cmd)
    75.         {
    76.             cmd.ReleaseTemporaryRT(ditherId);
    77.         }
    78.     }
    79. }
    upload_2023-3-8_21-44-44.png

    Thanks a lot for the help & tips!