Pause world rendering during game pause

Hello,

What would be the recommended way to stop world rendering during a game pause screen and only render UI updates while still retaining the most recent game frame?

In the editor, we can just use the following console command and it works as expected (paused game world with responsive UI):

showFlag.Rendering 0

However, in builds, every new UI frame gets rendered ontop of the previous frame including the previous frame’s UI, leading to lots of trailing and flickering.

We’re assuming we’ll have to find a way to set up a screen capture/separate buffer of the game for this to work. But I’m also wondering why the showFlag commands seems to behave differently in editor compared to builds and where in the code this behavior is set?

I’ve found some basic approaches in this thread: Pause rendering and continually display the last-rendered frame - #13 by AsdolgTheMaker

One post mentions a GetViewportScreenShot function, another one sets up a Scene Capture component to capture the world onto a render target. I’m unsure which approach would be best here.

Let me know if you need any more information.

Thank you!

Hi [mention removed]​,

I know that showFlag.Rendering does clear some extra buffers inside the editor that it does not in builds. Not sure about the reason but I’ve seen some other users having similar issues. Yes, there is a function where you can react after the screen capture has been done. There are other functions that might give you also the same result but some of them only work inside the editor and outside have a different behaviour.

The function you are looking at is OnScreenShotCaptured. In the following example you can see how to subscribe to the method. In my case after the screenshot is captured, you can then create a texture with the given pixels and use it inside your full ui. In my case the image captured was getting the alpha channel at 0. I think its something in my project but just letting the project if you need it.

UGameViewportClient* GVC = GetWorld()->GetGameViewport();
	if (GVC) {
		GVC->OnScreenshotCaptured().AddWeakLambda(this, [this](int32 W, int32 H, const TArray<FColor>& Pixels){
			// force opaque alpha for UI use
			TArray<FColor> Opaque = Pixels;
			for (auto& C : Opaque) C.A = 255;
			
			ScreenshotTexture = UMyRenderingLibrary::CreateTransientTextureFromPixels(Opaque, W, H, true);
			
			ShowPauseUIAndDisableWorldRendering(FrozenTexture);
		});
	}

You can also disable game rendering by using:

GEngine->GameViewport->bDisableWorldRendering = true;And pause the game with:

UGameplayStatics::SetGamePaused(World, true);

Lastly, in the widget blueprint, as a child of the UI canvas, I would recommend setting a black image at the background, and over it the screenshot image. If I’m correct, the scene render pass is the one that clears the back buffer, so just as a safe check, create a black image as the background (so that the back buffer gets cleared) and over it add your screenshot image. This should be a pretty safe to achieve what you are trying to get. You are overriding all the pixels at the end with the screenshot, so there should not be an issue with it.

Let me know if it worked for you :slightly_smiling_face:

Best,

Joan

Hi Joan,

Thank you for your detailed breakdown! This helped tremendously. We implemented this now and it works exactly as expected. :slight_smile:

Best,

Carl