Search Unity

Question Problem when upgrading Unity 2021 to 2022, URP for blit post process

Discussion in 'Universal Render Pipeline' started by termway, Mar 5, 2023.

  1. termway

    termway

    Joined:
    Jul 5, 2012
    Posts:
    84
    I'm trying to upgrade to Unity 2022.

    But my post process is broken if I use a RTHandle for a temporary render texure.

    Here a working code with the obsolete API (RenderTargetHandle for a temporary render texture).

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Rendering;
    3. using UnityEngine.Rendering.Universal;
    4.  
    5. public class BlitMaterialFeature : ScriptableRendererFeature
    6. {
    7.     class RenderPass : ScriptableRenderPass
    8.     {
    9.         private string profilingName;
    10.         private Material material;
    11.         private int materialPassIndex;
    12.         private RTHandle rtSource;
    13.         private RTHandle rtTempTextureHandle;
    14.         RenderTargetHandle tempTextureHandle;
    15.         ProfilingSampler profilingSampler = new ProfilingSampler("Blit");
    16.  
    17.         public RenderPass(string profilingName, Material material, int passIndex) : base()
    18.         {
    19.             this.profilingName = profilingName;
    20.             this.material = material;
    21.             this.materialPassIndex = passIndex;
    22.             //tempTextureHandle.Init("_TempBlitMaterialTexture");
    23.             //RTHandles.Initialize(Screen.width, Screen.height);
    24.             rtTempTextureHandle = RTHandles.Alloc("_TempBlitMaterialTexture2", name: "_TempBlitMaterialTexture2");
    25.         }
    26.  
    27.         public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
    28.         {
    29.             ConfigureTarget(rtTempTextureHandle);
    30.         }
    31.  
    32.         public void SetSource(RTHandle source)
    33.         {
    34.             rtSource = source;
    35.         }
    36.  
    37.         public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    38.         {
    39.             var cameraData = renderingData.cameraData;
    40.             if (cameraData.camera.cameraType != CameraType.Game)
    41.                 return;
    42.  
    43.             CommandBuffer cmd = CommandBufferPool.Get(profilingName);
    44.  
    45.             RenderTextureDescriptor cameraTextureDesc = renderingData.cameraData.cameraTargetDescriptor;
    46.             cameraTextureDesc.depthBufferBits = 0;
    47.  
    48.             //RenderingUtils.ReAllocateIfNeeded(ref rtTempTextureHandle, cameraTextureDesc, FilterMode.Bilinear);
    49.             cmd.GetTemporaryRT(tempTextureHandle.id, cameraTextureDesc, FilterMode.Bilinear);
    50.             //cmd.GetTemporaryRT(Shader.PropertyToID(rtTempTextureHandle.name), cameraTextureDesc, FilterMode.Bilinear);
    51.             using (new ProfilingScope(cmd, profilingSampler))
    52.             {
    53.                 //Blitter.BlitTexture(cmd, rtSource, rtTempTextureHandle, material, materialPassIndex);
    54.                 Blit(cmd, rtSource, /*rtTempTextureHandle*/tempTextureHandle.Identifier(), material, materialPassIndex);
    55.                 //Blitter.BlitCameraTexture(cmd, rtTempTextureHandle, rtSource);
    56.                 Blit(cmd, /*rtTempTextureHandle*/ tempTextureHandle.Identifier(), rtSource);
    57.             }
    58.  
    59.             context.ExecuteCommandBuffer(cmd);
    60.             cmd.Clear();
    61.             CommandBufferPool.Release(cmd);
    62.         }
    63.  
    64.         public void Dispose()
    65.         {
    66.             rtTempTextureHandle?.Release();
    67.         }
    68.     }
    69.  
    70.     [System.Serializable]
    71.     public class Settings
    72.     {
    73.         public Material material;
    74.         public int materialPassIndex = -1; // -1 means render all passes
    75.         public RenderPassEvent renderEvent = RenderPassEvent.AfterRenderingOpaques;
    76.     }
    77.  
    78.     [SerializeField]
    79.     private Settings settings = new Settings();
    80.  
    81.     private RenderPass renderPass;
    82.  
    83.     public Material Material
    84.     {
    85.         get => settings.material;
    86.     }
    87.  
    88.     public override void Create()
    89.     {
    90.         renderPass = new RenderPass(name, settings.material, settings.materialPassIndex);
    91.         renderPass.renderPassEvent = settings.renderEvent;
    92.     }
    93.  
    94.     public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    95.     {
    96.         if (renderingData.cameraData.cameraType == CameraType.Game)
    97.             renderer.EnqueuePass(renderPass); // letting the renderer know which passes will be used before allocation
    98.     }
    99.  
    100.     public override void SetupRenderPasses(ScriptableRenderer renderer, in RenderingData renderingData)
    101.     {
    102.         if (renderingData.cameraData.cameraType == CameraType.Game)
    103.         {
    104.             // Calling ConfigureInput with the ScriptableRenderPassInput.Color argument
    105.             // ensures that the opaque texture is available to the Render Pass.
    106.             renderPass.ConfigureInput(ScriptableRenderPassInput.Color);
    107.             renderPass.SetSource(renderer.cameraColorTargetHandle);  // use of target after allocation
    108.         }
    109.     }
    110. }

    Code (CSharp):
    1. RenderingUtils.ReAllocateIfNeeded(ref rtTempTextureHandle, cameraTextureDesc, FilterMode.Bilinear);
    Always give me a black screen in the Frame debugger.

    If I skip it I have null exception in the Blit method (rtTempTextureHandle is null).

    I look at these threads but I'm still helpless:
    https://forum.unity.com/threads/ren...lete-deprecated-in-favor-of-rthandle.1211052/
    https://forum.unity.com/threads/urp-13-1-8-proper-rthandle-usage-in-a-renderer-feature.1341164/
    https://docs.unity3d.com/Packages/c...iversal@13.1/manual/upgrade-guide-2022-1.html

    For example this version give me NullReferenceException
    Code (CSharp):
    1.     //RenderingUtils.ReAllocateIfNeeded(ref rtTempTextureHandle, cameraTextureDesc, FilterMode.Bilinear);
    2.             //cmd.GetTemporaryRT(tempTextureHandle.id, cameraTextureDesc, FilterMode.Bilinear);
    3.             cmd.GetTemporaryRT(Shader.PropertyToID(rtTempTextureHandle.name), cameraTextureDesc, FilterMode.Bilinear);
    4.             using (new ProfilingScope(cmd, profilingSampler))
    5.             {
    6.                 //Blitter.BlitTexture(cmd, rtSource, rtTempTextureHandle, material, materialPassIndex);
    7.                 Blit(cmd, rtSource, rtTempTextureHandle/*tempTextureHandle.Identifier()*/, material, materialPassIndex);
    8.                 //Blitter.BlitCameraTexture(cmd, rtTempTextureHandle, rtSource);
    9.                 Blit(cmd, rtTempTextureHandle/* tempTextureHandle.Identifier()*/, rtSource);
    10.             }

    NullReferenceException: Object reference not set to an instance of an object
    UnityEngine.Rendering.Universal.Internal.CopyDepthPass.ExecutePass (UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Rendering.Universal.Internal.CopyDepthPass+PassData passData, UnityEngine.Rendering.CommandBuffer& cmd, UnityEngine.Rendering.Universal.CameraData& cameraData, UnityEngine.Rendering.RTHandle source, UnityEngine.Rendering.RTHandle destination) (at ./Library/PackageCache/com.unity.render-pipelines.universal@14.0.6/Runtime/Passes/CopyDepthPass.cs:161)
    UnityEngine.Rendering.Universal.Internal.CopyDepthPass.Execute (UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Rendering.Universal.RenderingData& renderingData) (at ./Library/PackageCache/com.unity.render-pipelines.universal@14.0.6/Runtime/Passes/CopyDepthPass.cs:103)
    UnityEngine.Rendering.Universal.ScriptableRenderer.ExecuteRenderPass (UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Rendering.Universal.ScriptableRenderPass renderPass, UnityEngine.Rendering.Universal.RenderingData& renderingData) (at ./Library/PackageCache/com.unity.render-pipelines.universal@14.0.6/Runtime/ScriptableRenderer.cs:1446)
    UnityEngine.Rendering.Universal.ScriptableRenderer.ExecuteBlock (System.Int32 blockIndex, UnityEngine.Rendering.Universal.ScriptableRenderer+RenderBlocks& renderBlocks, UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Rendering.Universal.RenderingData& renderingData, System.Boolean submit) (at ./Library/PackageCache/com.unity.render-pipelines.universal@14.0.6/Runtime/ScriptableRenderer.cs:1402)
    UnityEngine.Rendering.Universal.ScriptableRenderer.Execute (UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Rendering.Universal.RenderingData& renderingData) (at ./Library/PackageCache/com.unity.render-pipelines.universal@14.0.6/Runtime/ScriptableRenderer.cs:1185)
    UnityEngine.Rendering.Universal.UniversalRenderPipeline.RenderSingleCamera (UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Rendering.Universal.CameraData& cameraData, System.Boolean anyPostProcessingEnabled) (at ./Library/PackageCache/com.unity.render-pipelines.universal@14.0.6/Runtime/UniversalRenderPipeline.cs:642)
    UnityEngine.Rendering.Universal.UniversalRenderPipeline.RenderSingleCameraInternal (UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Camera camera) (at ./Library/PackageCache/com.unity.render-pipelines.universal@14.0.6/Runtime/UniversalRenderPipeline.cs:527)
    UnityEngine.Rendering.Universal.UniversalRenderPipeline.Render (UnityEngine.Rendering.ScriptableRenderContext renderContext, System.Collections.Generic.List`1[T] cameras) (at ./Library/PackageCache/com.unity.render-pipelines.universal@14.0.6/Runtime/UniversalRenderPipeline.cs:369)
    UnityEngine.Rendering.RenderPipeline.InternalRender (UnityEngine.Rendering.ScriptableRenderContext context, System.Collections.Generic.List`1[T] cameras) (at <0ae5
     
  2. lcagustini

    lcagustini

    Joined:
    Oct 27, 2020
    Posts:
    1
    Hey
    I had the exact same problem, and from the Frame Debugger, it seemed that the ReAllocateIfNeeded function was creating a RT with no color format.
    So I got it working by simply creating a descriptor instead of using the camera one (maybe it is not initialized correctly?)

    Code (CSharp):
    1.  
    2.  
    3. public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
    4. {
    5.     base.OnCameraSetup(cmd, ref renderingData);
    6.  
    7.     RenderTextureDescriptor descriptor = new RenderTextureDescriptor(128, 128, RenderTextureFormat.Default);
    8.     RenderingUtils.ReAllocateIfNeeded(ref effectColorTarget, descriptor, name: "_Pixel_Buffer");
    9. }
    10.  
    11.  
    The GetTemporaryRT API seems to be "deprecated", as in the new versions of URP expect you to use ReAllocateIfNeeded from what I could gather, this API is massively under-documented.
    As I am trying to make a pixel effect, the fixed RT size is what I want, but you probably want to use the Screen size for yours.
    Hope this helps!
     
    clabbe likes this.