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.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

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:
    48
    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.