Freezing Shaders in Godot
Introduction⌗
Pausing your game in Godot is, as you can see from official docs, quite easy.
In my project I make use of a lot of different shaders
and I, incorrectly,
assumed that when you pause a game, the shaders
would pause along
with the rest of the nodes
. Turns out shaders
are programs
that are
always running on the GPU and never stop, unless you add specific logic
to the shader
to support this.
Solution⌗
So I had to come up with another solution (more of a cheat really):
- When you pause the game, capture the screen.
- Take the resulting
texture
and assign it to thetexture
property
of anTextureRect
which is displayed over the originalshader
.
Scene Setup⌗
Image the following scene
with a ColorRect
and a TextureRect
.
The ColorRect
displays the shader
.
The TextureRect
will display the frozen shader
.
Node2D
|--ColorRect : Shader
|--TextureRect : PauseNode (hidden)
The code⌗
I’m a c# guy but it’s very easy to translate this to gdscript
.
Imagine the following method that toggles
the paused
state.
public void TogglePause()
{
var pauseNode = GetNode<TextureRect>("PauseNode");
if (!pauseNode.Visible)
{
viewport.RenderTargetClearMode = Viewport.ClearMode.OnlyNextFrame;
pauseNode.Texture = viewport.GetTexture();
pauseNode.Visible = true;
}
else
{
viewport.RenderTargetClearMode = Viewport.ClearMode.Always;
pauseNode.Texture?.Dispose();
pauseNode.Visible = false;
}
}
Pausing⌗
First you have to get the ViewPort and set the RenderTargetClearMode
to ClearMode.OnlyNextFrame. Next you get the Texture
and
assign it to the Texture
property of the TextureRect
.
Resuming⌗
Simply reverse the procedure and you’re done.