Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question How to apply mutiple shaders in a single ScriptableRenderPass

Discussion in 'Universal Render Pipeline' started by Domboo, Sep 14, 2022.

  1. Domboo

    Domboo

    Joined:
    Apr 1, 2022
    Posts:
    2
    Hi everyone,

    I currently try to implement a post processing blooming effect. I found an approach, which I try to follow (Link). The approach uses the standard render pipeline. Because I'm working with the URP, I try to find a way how to realize the OnRenderImage function in my SciptableRenderPass.
    By help of other threads I came to the mind, I could use the Blit function in the Execute function of my ScriptableRenderPass, which works perfectly fine so far. Because I want to downsample and upsample the camera image, using the interim results, I tried to use mutiple Blits. Unfortunately I had to realize that only the shader of the last Blit execution is used on the camera image. For testing I use simple tinting shaders.

    Code (CSharp):
    1. public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    2.     {
    3.         if (blitRenderMaterial == null)
    4.         {
    5.             Debug.LogError("Material not created");
    6.             return;
    7.         }
    8.  
    9.         if (!renderingData.cameraData.postProcessEnabled) return;
    10.  
    11.         CommandBuffer cmd = CommandBufferPool.Get(k_RenderTag);
    12.         Render(cmd, ref renderingData);
    13.         context.ExecuteCommandBuffer(cmd);
    14.         CommandBufferPool.Release(cmd);
    15.     }
    16.  
    17.  
    18. void Render(CommandBuffer cmd, ref RenderingData renderingData)
    19.     {
    20.         RenderTargetIdentifier source = currentTarget;
    21.         int shaderPass = 0;
    22.         RenderTargetHandle tempTexture = new RenderTargetHandle();
    23.  
    24.         tempTexture.Init("My temporary Texture");
    25.         RenderTextureDescriptor cameraTextureDesc = renderingData.cameraData.cameraTargetDescriptor;
    26.         cameraTextureDesc.depthBufferBits = 0;
    27.         cmd.GetTemporaryRT(tempTexture.id, cameraTextureDesc, FilterMode.Bilinear);
    28.  
    29.         cmd.Blit(source, tempTexture.Identifier(), blitRenderMaterial, shaderPass);  // Green tinting shader
    30.         cmd.Blit(tempTexture.Identifier(), source, blitRenderMaterial2, shaderPass);  // Red tinting shader
    31.  
    32.         cmd.ReleaseTemporaryRT(tempTexture.id);
    33.     }

    Can anyone tell me if my approach to use mutiple blits in a single RenderPass is valid? Is it even possible to execute this function more than 1 time? I also read about the DrawMesh function. Could that be a working alternative? Are there other, better ways how to get access on the interim results? I am new to unity and struggling with this topic for days. I am glad about every answer!
     
  2. ElliotB

    ElliotB

    Joined:
    Aug 11, 2013
    Posts:
    266
    Yes, you can use multiple blits in a ScriptableRenderPass. You can also create additional render targets to blit to/from, using your shaders, as you do above. If you want to use your additional render targets in other passes, move the cleanup to FrameCleanup() (a familiar example of this would be the shadowcasting passes, which create targets used in subsequent rendering passes).

    You can also use the Frame Debugger to inspect the inputs and outputs of each blit during your Pass. There's also RenderDoc, which is extremely useful for debugging the draw calls. These may help you find out why your other blits do not work. Are you certain the blit source texture is being correctly sampled in your shader?
     
    Domboo likes this.
  3. Domboo

    Domboo

    Joined:
    Apr 1, 2022
    Posts:
    2
    Thank you for your reply! By using the tools I found out that the blits were correctly executed. But your question lead me to check the shaders. The reason was that I used the Scene Color function in shader graph instead of sampling the MainTexture. By changing this the blits do their job now. Thanks for the hints! Helped me a lot, even if it was such a simple failure :)
     
    ElliotB likes this.