Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Question Custom Effect Pass vs Built In OnRender absolutely tanks performance

Discussion in 'Universal Render Pipeline' started by morphex, Nov 29, 2022.

  1. morphex

    morphex

    Joined:
    Dec 18, 2012
    Posts:
    99
    I am trying to implement a custom Effect Pass that works in BuiltIn


    Code (CSharp):
    1.  void OnRenderImage(RenderTexture source, RenderTexture destination) {
    2.         kuwaharaMat.SetInt("_KernelSize", kernelSize);
    3.         kuwaharaMat.SetInt("_N", 8);
    4.         kuwaharaMat.SetFloat("_Q", sharpness);
    5.         kuwaharaMat.SetFloat("_Hardness", hardness);
    6.         kuwaharaMat.SetFloat("_Alpha", alpha);
    7.         kuwaharaMat.SetFloat("_ZeroCrossing", zeroCrossing);
    8.         kuwaharaMat.SetFloat("_Zeta", useZeta ? zeta : 2.0f / 2.0f / (kernelSize / 2.0f));
    9.  
    10.         var structureTensor = RenderTexture.GetTemporary(source.width, source.height, 0, source.format);
    11.         Graphics.Blit(source, structureTensor, kuwaharaMat, 0);
    12.         var eigenvectors1 = RenderTexture.GetTemporary(source.width, source.height, 0, source.format);
    13.         Graphics.Blit(structureTensor, eigenvectors1, kuwaharaMat, 1);
    14.         var eigenvectors2 = RenderTexture.GetTemporary(source.width, source.height, 0, source.format);
    15.         Graphics.Blit(eigenvectors1, eigenvectors2, kuwaharaMat, 2);
    16.         kuwaharaMat.SetTexture("_TFM", eigenvectors2);
    17.  
    18.         RenderTexture[] kuwaharaPasses = new RenderTexture[passes];
    19.  
    20.         for (int i = 0; i < passes; ++i) {
    21.             kuwaharaPasses[i] = RenderTexture.GetTemporary(source.width, source.height, 0, source.format);
    22.         }
    23.  
    24.         Graphics.Blit(source, kuwaharaPasses[0], kuwaharaMat, 3);
    25.  
    26.         for (int i = 1; i < passes; ++i) {
    27.             Graphics.Blit(kuwaharaPasses[i - 1], kuwaharaPasses[i], kuwaharaMat, 3);
    28.         }
    29.  
    30.         //Graphics.Blit(structureTensor, destination);
    31.         Graphics.Blit(kuwaharaPasses[passes - 1], destination);
    32.  
    33.         RenderTexture.ReleaseTemporary(structureTensor);
    34.         RenderTexture.ReleaseTemporary(eigenvectors1);
    35.         RenderTexture.ReleaseTemporary(eigenvectors2);
    36.         for (int i = 0; i < passes; ++i) {
    37.             RenderTexture.ReleaseTemporary(kuwaharaPasses[i]);
    38.         }
    39.     }
    and this is my attempt at turning in in a custom Feature with Custom pass:


    Code (CSharp):
    1.  class KuawaharaRenderPass : ScriptableRenderPass
    2.     {
    3.         private ProfilingSampler m_ProfilingSampler = new ProfilingSampler("KuawaharaPass");
    4.         private static Material _material;
    5.  
    6.  
    7.         private bool isUsingA = false;
    8.  
    9.         private RTHandle _swapBufferA;
    10.         private RTHandle _swapBufferB;
    11.         private RTHandle _TFMBuffer;
    12.  
    13.         public RTHandle NextBuffer
    14.         {
    15.  
    16.             get
    17.             {
    18.                 isUsingA = !isUsingA;
    19.                 if (!isUsingA)
    20.                 {
    21.                     return _swapBufferB;
    22.                 }
    23.                 else
    24.                 {
    25.                     return _swapBufferA;
    26.                 }
    27.             }
    28.         }
    29.  
    30.  
    31.         private Settings _settings;
    32.  
    33.         private static readonly int _TFMID = Shader.PropertyToID("_TFM");
    34.  
    35.         public KuawaharaRenderPass(Material material)
    36.         {
    37.             this.profilingSampler = m_ProfilingSampler;
    38.             _material = material;
    39.             renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
    40.         }
    41.         public void Setup(in RenderingData renderingData, Settings settings)
    42.         {
    43.             this._settings = settings;
    44.  
    45.             ConfigureTarget(renderingData.cameraData.renderer.cameraColorTargetHandle);
    46.             ConfigureInput(ScriptableRenderPassInput.Color);
    47.             _material.SetInt("_KernelSize", _settings.kernelSize);
    48.             _material.SetInt("_N", 8);
    49.             _material.SetFloat("_Q", _settings.sharpness);
    50.             _material.SetFloat("_Hardness", _settings.hardness);
    51.             _material.SetFloat("_Alpha", _settings.alpha);
    52.             _material.SetFloat("_ZeroCrossing", _settings.zeroCrossing);
    53.             _material.SetFloat("_Zeta", _settings.useZeta ? _settings.zeta : 2.0f / 2.0f / (_settings.kernelSize / 2.0f));
    54.         }
    55.  
    56.  
    57.  
    58.  
    59.         public void Dispose()
    60.         {
    61.             _swapBufferA?.Release();
    62.             _swapBufferB?.Release();
    63.             _TFMBuffer?.Release();
    64.         }
    65.  
    66.         public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
    67.         {
    68.             base.OnCameraSetup(cmd, ref renderingData);
    69.             var descriptor = renderingData.cameraData.cameraTargetDescriptor;
    70.             descriptor.depthBufferBits = (int)DepthBits.None;
    71.             RenderingUtils.ReAllocateIfNeeded(ref _swapBufferA, descriptor, name: "_swapBufferA");
    72.             RenderingUtils.ReAllocateIfNeeded(ref _swapBufferB, descriptor, name: "_swapBufferB");
    73.             RenderingUtils.ReAllocateIfNeeded(ref _TFMBuffer, descriptor, name: "_tfmBuffer");
    74.         }
    75.  
    76.         public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    77.         {
    78.             var cameraData = renderingData.cameraData;
    79.             var cmd = CommandBufferPool.Get();
    80.             // ExecutePass(m_PassData, renderingData.cameraData, renderingData.commandBuffer);
    81.             if (_material == null)
    82.             {
    83.                 Debug.Log("NO material");
    84.                 // should not happen as we check it in feature
    85.                 return;
    86.             }
    87.  
    88.             if (cameraData.isPreviewCamera)
    89.             {
    90.                 return;
    91.             }
    92.  
    93.  
    94.  
    95.             using (new ProfilingScope(cmd, profilingSampler))
    96.             {
    97.  
    98.                 var source = cameraData.renderer.cameraColorTargetHandle;
    99.                 Blitter.BlitCameraTexture(cmd, source, _swapBufferA);
    100.                 Blitter.BlitCameraTexture(cmd, _swapBufferA, _swapBufferB, _material, 0);
    101.                 Blitter.BlitCameraTexture(cmd, _swapBufferB, _swapBufferA, _material, 1);
    102.                 Blitter.BlitCameraTexture(cmd, _swapBufferA, _TFMBuffer, _material, 2);
    103.  
    104.                 _material.SetTexture(_TFMID, _TFMBuffer);
    105.  
    106.  
    107.  
    108.                  Blitter.BlitCameraTexture(cmd, source, _swapBufferA, _material, 3);
    109.                  Blitter.BlitCameraTexture(cmd, _swapBufferA, _swapBufferB, _material, 3);
    110.                  Blitter.BlitCameraTexture(cmd, _swapBufferB, _swapBufferA, _material, 3);
    111.                  Blitter.BlitCameraTexture(cmd, _swapBufferA, _swapBufferB, _material, 3);
    112.  
    113.  
    114.                 Blitter.BlitCameraTexture(cmd, _swapBufferB, source);
    115.  
    116.             }
    117.  
    118.             context.ExecuteCommandBuffer(cmd);
    119.             cmd.Clear();
    120.             CommandBufferPool.Release(cmd);
    121.  
    122.         }
    123.  
    124.  
    125.     }

    The thing is: BuiltIn = 150FPS and URP < 20.

    I am must be doing something obviously wrong here, the shader code is 99% the same, apart from using URP builtins structures on HLSL side of things. But the performance is absolutely trash.

    Am I doing anything wrong?