RenderPipeline.InternalRender() doing per frame GC Alloc with 2+ Render Texture cameras

Hello! I’m getting some per-frame GC allocs coming from the Universal Render Pipeline, specifically the GetCameras() and SortCameras() functions. I have 3 cameras set to ‘base’ that are outputting to RenderTextures which I’m combining in funky ways for some 2D lighting and reflection effects, and one camera rendering the combined rendertexture at the end. This combination of cameras seems to be making CetCameras() and SortCameras() calls happen every frame, which is allocating unnecessary memory!

Is this a bug, or something I can fix on my end? It happens in both the foward renderer and the 2D renderer setups.


2 Likes

Edit: Thought I had a genius insight in to what this is, but it wasn’t genius at all, haha. The problem still stands, having multiple cameras wth at least one going to a Render Texture causes Get/SortCameras() to create memory allocations when doing an Array.Resize. I submitted a bug for this with a test project regarding the 2D Renderer, but it stands in the Forward Renderer too.

This is tested on URP 7.3.1 and Unity 2019.3.7

Still getting this issue with URP 7.4.1 and Unity 2019.4.1 - if I have more that 2 cameras rendering (Base, Overlay, RenderTexture) I get RenderPipelineManager.GetCameras() creating garbage every frame. I can’t believe I’m the only person using the URP that is running in to this issue - is anyone else getting this, or knows how to overcome it?

The issue is tracked here but it seems to be attributed to the 2D Renderer rather than the Forward Renderer as a whole -

Is this going to get backported to 7 any time soon?

1 Like

It looks like a fix has been checked in for the issue, hooray! [9.x.x] Fix allocation caused when sorting cameras in URP. by phi-lira · Pull Request #268 · Unity-Technologies/Graphics · GitHub

It’s supposed to be in 7.4.1 looking at the changelog, however, but I’m still getting the issue - Sort Cameras isn’t creating garbage now, but GetCameras() still is!

Weirdly I can’t find the GetCameras() function anywhere in the URP .cs files… @phil_lira given you made the fix, do you have any idea what I can do to get rid of this remaining GC allocation every frame?

1 Like

Unfortunately, I couldn’t stand it and gave up URP, 2d lighting, shader graph and new post processing. I come back to using LWRP and post processing stack + lighting 3d.

Heyhey!
Can you report this as a bug for me?
The fix for this needs to be done in core and I believe I know where the culprit is. It would speed up my work to have a good repro if possible.

Hello! I have submitted this as a bug and sent some additional repro steps in an email. It’s really easy to recreate though, it happens right out of the box:

With 2019.4.1 and URP 7.4.1 installed do the following:

  • Create a new project with the ‘Universal Render Pipeline’ template.
  • Hit ‘play’ in the editor and check the profiler - there will be no GC Allocs made every frame with one camera in the scene.
  • Add an additional camera in the editor (removing the audio listener) and hit play again. Observe that 'RenderPipelineManager.DoRenderLoop_Internal() is now allocating memory every frame.
  • Continue to add additional cameras to increase the per-frame memory allocation.

You can have one additional camera targeting a rendertexture to avoid this.

1 Like

Thank you!
Will take a look at this. Can you give me the case ID?

Sure! It’s https://issuetracker.unity3d.com/issues/urp-scriptablerendercontext-dot-getcamera-array-dot-resize-creates-garbage-every-frame-when-more-than-one-camera-is-active - thanks so much for looking in to this!

1 Like

Any news or updates on this?

I’ve spotted that in the frame debugger, the camera that is causing GC alloc per frame when enabled is being rolled in to the primary Render Camera’s drawing stack, and I’m not sure why that is the case:

I’m not exactly sure what I’ve done to get my ‘final composite’ camera gets it’s own Render Camera hierarchy but the Minimap doesn’t. They’re all using separate ForwardRenderer objects so should be unique!

Bumping again. Still an issue in 2020.1 with the URP 8.2.0 or the 9.0.0.35 packages.

Hey,
I just poked the dev about this. I’ll hopefully be able to give you some updates later this week.

Hey guys, any news on this issue?
im having 128B allocated every frame on android, samsung s20+,
using unity ver 2019.4.5f1.

i also have multiple cameras in the scene (one regular, one overlay)

Same with me in unity 2020.2.4

I use camera.render to control the rendering process, but I get a 188b gc every render.

According to this Changelog Changelog | Universal RP | 10.2.2 this should have been fixed in 10.1.0, but it is not:

Coming up to a year anniversary since I reported this :smile: I saw a fix checked in to the URP Github months and months ago, but that’s no longer accessible now. Any idea when this might be actually fixed?

Any updates on this? I’m getting 188b gc on every frame.

There’s a ticket for this at: Unity Issue Tracker - [URP] ScriptableRenderContext.GetCamera -> Array.Resize creates garbage every frame when more than one camera is active

The issue seems to be fixed in URP10.1.0 but its for Unity 2021.1.0a1.

Any idea if this will be backported to 2019.4 LTS or other versions?

I think this must be fixed -I really hope it will be backported soon.

I am also getting this. Has anyone come up with any work around?

Same issue , 78.6KB in empty scene (10.7.0) . Any ideas ?