Download

Best way to programatically render from different camera locations?

Hi, I’m interested in finding the best way to programatically render a scene from a list of predefined camera positions/orientations, capturing the framebuffer at each position. I intend to do some processing on the framebuffer at each location in realtime so saving to a file/movie is undesirable.

I’m currently doing this by placing a custom Actor in the scene that on every Tick() moves the player camera and then calls FScreenshotRequest::RequestScreenshot(). When I’m done I then read the files back in.

This is obviously really slow, and the file writes are unnecessary. I would also prefer not to have to tick the game loop as well.

I’ve tried grabbing the Viewport directly and pumping it through a series of TakeHighResScreenShot() / Draw() commands–and this works but I can’t seem to move the camera in between draws. The camera doesn’t move until the game loop ticks.

Any thoughts or ideas? Thanks!

What is your goal?

Probably one of the limitations that requires the need to save the files to the disk is that otherwise it would have to be saved to GPU memory which could be a problem.

It would indeed help if you explained what you want to achieve with it. In most cases you would use RenderTextures if you want to render a different camera view and directly use it in your game, but without more details on what you want to do it’s hard to say if that’s the way to go for you.

My goal is to be able to run some processing in the background over a set of buffer captures taken at multiple camera locations.

Rendering to a texture sounds promising. Thanks for the tip. I tried setting up a SceneCapture2D and targeting it to a texture but it doesn’t seem to work if I set the target to anything larger than 512x512. Is this a known limitation? Two questions:

  • Is it possible to have a 2048x2048 target? I want it to look exactly like in-game so I would like to super-sample at a higher resolution (emulating FSAA).
  • How would I “pump” rendering on the target? I would like to, from code, move the SceneCapture2D actor around, force a draw on the render target, grab the buffer, repeat.

Thanks for your help so far!

It appears if I set the target size to 2048x2048, the texture format to R8B8G8A8 (HDR off), and the “capture source” of the SceneCapture2D actor to “Final Color (LDR with PostProcess)” then rendering to the texture properly displays in the Editor. However once I boot the game I only see the top left corner of the camera in the texture, the rest is green.

Discovered this is due to FSceneRenderTargets::ComputeDesiredSize() that is clamping the render texture to the size of the screen. It looks you can override this behavior with the console variable r.SceneCaptureResizeMethod.

Hi moof2k,

Did you manage to grab the contents of the framebuffer? I am doing something similar and at the moment, writing to disk… which is horrendous. Also, how did you pump the viewport “through a series of TakeHighResScreenShot() / Draw() commands-”?

Kind regards,
Rich