Looking for a faster way to draw to a render target repeatedly

I’m currently making a 2D bullet hell game, where all of the bullets are drawn to a render target using BeginDrawCanvasToRenderTarget, and then for each bullet calling DrawTexture, and then after the loop calling EndDrawCanvasToRenderTarget. All of the bullets are the same texture.

I started running into performance issues with a relatively low amount of bullets. After doing some testing and trace profiling, the slowdown seems to come from the Render thread, specifically “FRDGBuilder::ExecutePasses”. More bullets leads to more calls of this. I’m guessing its because of each DrawTexture call, so what else can I do to draw one texture to a render target many times quickly?

I don’t know a lot about graphics programming, but I do know that GPUs are good at drawing from the same texture many times, through things like batch and instanced rendering. Is there a way I can do those in Unreal onto a render target?

I feel like the obvious question needs to be asked here: Why are you using render targets for the bullets at all?

It might be possible with enough effort but this is probably not a good way to do whatever you’re trying to do.

The gameplay happens in a smaller, off-centered portion of the window, so it made sense to do a render target for that instead of trying to figure out where to offset a camera so that the off-center-ness would cancel out. There’s a 3D background there, but the gameplay on top needed to be ‘pixel perfect’ 2D according to the designer. I couldn’t put the 2D gameplay in the world for a few reasons:

  1. if i put it in front of the background camera, it would get affected by visual effects on the camera.
  2. i need to draw things in a specific order so that certain thing are on top, which wont work for a perspective camera while keeping sizes the same and textures pixel-perfect.
  3. To solve that, i would need a different camera, but the way alpha works with scene capture components doesn’t work for that.
  4. I tried putting the background render target in world and putting everything in front with an orthographic scene capture component, but something wasn’t working right

Also, there’s various shader/material effects that needed to apply to the entire 2D gameplay and 3D background but not the rest of the window. That was really easy to do with everything on a render target.
Lastly, for the life of me i could not figure out how to get UMG widgets to keep their %-of-window relative size when the screen resizes, and render targets fixed that.