Screenshot at runtime without stutter

Hello,
is there any proper what to take a screenshot (for save system) at runtime without making the game stutter? I have a custom async save system that works nicely and is independent from the screenshot (which is taken prior to save), the problem I incur is that anytime I take a screenshot, the game stutters for a couple of frames.

I have been trying to use scene capture and then read pixels from the target textures. I have been trying to use the same way RequestScreenshot works, but without saving to file, yet it stutters once again (for both using current viewport and making a screenshot from slate). The thing is, that there is a hitch on the rendering thread, probably due to some command flushes down the way, but I have also noticed that mapping texture resource to d3d context (down the way of read pixels) is slow.

On top of that, I have been trying hacky ways of reading pixels from render target, mostly just using custom enqueue render command bypassing most of the flushes on readpixels function, going straight for the GDynamicRHI->RHIReadSurfaceData and making async callback to game thread once it finishes, yet it still stutters and causes spikes on rendering thread.

Any tips?

Edit: My screenshot is very small, 128x128
I have been testing the performance on shipping build and on test build, with console enabled for the latter.

Bump, anyone please?

Since the last time I have also tried using a single scene capture component (since previously it was spawned with an custom scene capture actor and then destroyed) and calling CaptureSceneDeferred(), but unfortunately it still doesn’t help.

Right now, the code looks like this:

textureRenderTarget->InitCustomFormat(resolution.X, resolution.Y, PF_B8G8R8A8, false);

SceneCaptureComponent->TextureTarget = textureRenderTarget;
SceneCaptureComponent->CaptureSource = ESceneCaptureSource::SCS_FinalColorLDR;
SceneCaptureComponent->CaptureScene(); // Or deferred

TArray<FColor> colorData;
colorData.Reserve(resolution.X * resolution.Y);

textureRenderTarget->GameThread_GetRenderTargetResource()->ReadPixels(colorData); // Or custom enqueue render command going straight for GDynamicRHI->RHIReadSurfaceData
1 Like

Bump, same issue. Anyone?