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.