API for getting a rendered frame

As a Roblox developer, it is currently impossible to get, and hard to efficiently recreate, a “freeze-frame” of an already rendered frame.

For example, if I wanted to display an rendered frame, I would need to clone everything the player sees into a viewport frame, keeping in mind that that doesn’t include UI and will produce a lower quality version of the frame.

In my mind, that doesn’t sound so efficient, thus I suggest adding a new service which would provide APIs tied to Roblox’s rendering system. If a separate service is too much to ask for, then adding an API to an already existing service should do the work.

If Roblox were to add this, many other developers and I, would be able to create a lot of stuff that we usually couldn’t so easily… Some examples that could come to my mind are fading effects (like the one used in the flashbang effect in CSGO), transition effects, delay/nausea effects, flashbacks etc…

When it comes to the second API recommended (view below), developers could pause rendering in order to save some resources in, for example, a UI-only game (which are rare, but do exist).


I suggest the following APIs (will list them under RenderingService since I don’t know to which already existing services would they belong to):

RenderingService:GetFrameImage()
RenderingService:GetCurrentFrameId(): number
RenderingService:GetSavedFrames(): {}

Returns an table of saved frames, their frame ids and their temporary image ids.

RenderingService:GetFrameImage(includeUI: boolean): string, number

Returns a number representing the frame id captured and temporary asset id (rbxtemp://) of an image of the current frame, with the image's size being player's viewport's absolute size.

However, also set a limit for the frames that are saved, for example, 3~5 frames saved max. After the limit has been passed, delete the previous frames. This could be an way to save memory.

The first two methods could be used by developers for their specific reasons.


or, a more riskier method…

RenderingService:SetPaused()
RenderingService:IsPaused(): boolean
RenderingService:SetPaused(state: boolean)

Based on the state passed, the rendering gets paused or resumed. If paused, last frame that was rendered before pausing will remain visible.

This is a riskier method, since if the developer forgets to unpause the rendering, the user could be left with a frozen screen. + Not a lot could be done with the frozen frame, unlike the last method which provides an image which can be moved, scaled, modified… using an ImageLabel.


10 Likes

I would also love to see RunService:Set3dRenderingEnabled() unlocked to use in game scripts. It makes no sense why it should be locked to corescripts, while it would help with UI based games optimization.

5 Likes

i think this should be expanded for canvasgroups & viewportframes as well. being able to render something once in a viewport frame and use that as a texture could really help performance in some use cases

I’ve thought that this method just disables Direct3D so even non-QT UI won’t even work. I might be wrong though.


I can see the SetPaused having other use cases, like for menus and other modal dialogs. I want both included though, since some sort of killcam would be an epic feature for many games.

1 Like

Actually, ViewportFrames will only render when their contents or their 2D size changes. So, as long as you don’t change those, it’s basically just an ImageLabel.