Search Unity

Question Only opaque object post-processing and multiple passes in SRP

Discussion in 'General Graphics' started by wechat_os_Qy00ZsXVumo1o8syrISdbhhOI, Nov 29, 2021.

  1. wechat_os_Qy00ZsXVumo1o8syrISdbhhOI

    wechat_os_Qy00ZsXVumo1o8syrISdbhhOI

    Joined:
    Apr 6, 2020
    Posts:
    3
    In my scriptable render pipeline, I added a post-processing after rendering opaque objects, and then continued rendering skybox and transparent objects.

    But when I add multiple passes to the transparent object (for shell-based fur rendering), I found that rendering results were problematic on the phone when the number of passes exceeded 2. Or there is no problem but GMEM_LoadDepth will be triggered (this will cause serious bandwidth issues even though I have set LoadAction to DontCare)

    I tried many ways, but I couldn't solve the problem. Is this a Unity Bug, or is there something wrong with my part of the design?

    the codes are as follows:
    Code (CSharp):
    1.         // Opaque
    2.         SortingSettings sortingSettings = new SortingSettings(camera)
    3.         {
    4.             criteria = SortingCriteria.CommonOpaque
    5.         };
    6.         DrawingSettings drawingSettings = new DrawingSettings(BPipline.bshaderTagIds[0], sortingSettings)
    7.         {
    8.             enableDynamicBatching = useDynamicBatching,
    9.             enableInstancing = useGPUInstancing,
    10.             perObjectData =
    11.             PerObjectData.ReflectionProbes |
    12.             PerObjectData.Lightmaps |
    13.             PerObjectData.ShadowMask |
    14.             PerObjectData.OcclusionProbe |
    15.             PerObjectData.LightProbe |
    16.             PerObjectData.LightProbeProxyVolume |
    17.             PerObjectData.OcclusionProbeProxyVolume |
    18.             lightsPerObjectFlags
    19.         };
    20.         // Set Multi-Pass
    21.         for (int i = 1; i < BPipline.bshaderTagIds.Length; ++i)
    22.         {
    23.             drawingSettings.SetShaderPassName(i, BPipline.bshaderTagIds[i]);
    24.         }
    25.         FilteringSettings filteringSettings = new FilteringSettings(RenderQueueRange.opaque);
    26.         context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
    27.  
    28.         // PostProcess Before Transparent
    29.         if (postprocessProfiler.isActive && postprocessSettings.ssao.enable)
    30.         {
    31.             postprocessProfiler.Render_BeforeTransparent(colorBufferId, renderTargetBinding);
    32.         }
    33.  
    34.         context.DrawSkybox(camera);
    35.  
    36.         // Transparent
    37.         sortingSettings.criteria = SortingCriteria.CommonTransparent;
    38.         drawingSettings.sortingSettings = sortingSettings;
    39.         filteringSettings.renderQueueRange = RenderQueueRange.transparent;
    40.         context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
    Code (CSharp):
    1.     public void Render_BeforeTransparent(int colorBuffer,    RenderTargetBinding renderTargetBinding)
    2.     {
    3.         PostProcessSettings.SSAO_Settings ssao = postprocessSettings.ssao;
    4.         int width = camera.pixelWidth;
    5.         int height = camera.pixelHeight;
    6.  
    7.         int sourceTarget = colorBuffer;
    8.         int destTarget = destinationId;
    9.         commandBuffer_beforeTransparent.GetTemporaryRT(destinationId, width, height, 0, postprocessSettings.filterMode, postprocessSettings.renderTextureFormat);
    10.  
    11.         Vector2Int rtSize = new Vector2Int(width >> ssao.downSample, height >> ssao.downSample);
    12.         commandBuffer_beforeTransparent.GetTemporaryRT(ssaoRt0, rtSize.x, rtSize.y, 0, FilterMode.Bilinear, GraphicsFormat.R8_UNorm);
    13.         commandBuffer_beforeTransparent.GetTemporaryRT(ssaoRt1, rtSize.x, rtSize.y, 0, FilterMode.Bilinear, GraphicsFormat.R8_UNorm);
    14.  
    15.         commandBuffer_beforeTransparent.SetGlobalVector("_AO_Scales", new Vector4(ssao.aoStrength, ssao.sampleScale / rtSize.x, ssao.sampleScale / rtSize.y, 0.5f));
    16.         Draw_BeforeTransparent(destTarget, ssaoRt0, Pass.SSAO);
    17.  
    18.         for (int i = 0; i < 3; i++)
    19.         {
    20.             commandBuffer_beforeTransparent.SetGlobalVector("_BlurOffset", new Vector4(ssao.blurScale / rtSize.x, 0.0f));
    21.             Draw_BeforeTransparent(ssaoRt0, ssaoRt1, Pass.GaussianBlur);
    22.  
    23.             commandBuffer_beforeTransparent.SetGlobalVector("_BlurOffset", new Vector4(0.0f, ssao.blurScale / rtSize.y));
    24.             Draw_BeforeTransparent(ssaoRt1, ssaoRt0, Pass.GaussianBlur);
    25.         }
    26.  
    27.         commandBuffer_beforeTransparent.SetGlobalTexture("_PostProcessBlend", ssaoRt0);
    28.         Draw_BeforeTransparent(sourceTarget, destTarget, Pass.BlendMulR);
    29.  
    30.         // Because I am using MRT, I need to reset back to MRT after the post-processing (LoadAction is DontCare)
    31.         commandBuffer_beforeTransparent.SetGlobalTexture(sourceId, destTarget);
    32.         commandBuffer_beforeTransparent.SetRenderTarget(renderTargetBinding);
    33.         commandBuffer_beforeTransparent.DrawProcedural(Matrix4x4.identity, postprocessSettings.Material, (int)Pass.Copy, MeshTopology.Triangles, 3);
    34.  
    35.         commandBuffer_beforeTransparent.ReleaseTemporaryRT(ssaoRt0);
    36.         commandBuffer_beforeTransparent.ReleaseTemporaryRT(ssaoRt1);
    37.         commandBuffer_beforeTransparent.ReleaseTemporaryRT(destinationId);
    38.  
    39.         Execute_BeforeTransparent();
    40.     }