Up to date
This page is up to date for Godot 4.0
.
If you still find outdated information, please open an issue.
Custom post-processing¶
Introduction¶
Godot provides many post-processing effects out of the box, including Bloom, DOF, and SSAO. However, advanced use cases may require custom effects. This article explains how to write your own custom effects.
The easiest way to implement a custom post-processing shader is to use Godot's built-in ability to read from the screen texture. If you're not familiar with this, you should read the Screen Reading Shaders Tutorial first.
Single pass post-processing¶
Post-processing effects are shaders applied to a frame after Godot has rendered
it. To apply a shader to a frame, create a CanvasLayer, and give it a ColorRect. Assign a
new ShaderMaterial to the newly created
ColorRect
, and set the ColorRect
's layout to "Full Rect".
Your scene tree will look something like this:

Note
Another more efficient method is to use a BackBufferCopy to copy a region of the screen to a buffer and to
access it in a shader script through a sampler2D
using
hint_screen_texture
.
Note
As of the time of writing, Godot does not support rendering to multiple buffers at the same time. Your post-processing shader will not have access to normals or other render passes. You only have access to the rendered frame.
For this demo, we will use this Sprite of a sheep.

Assign a new Shader to the ColorRect
's
ShaderMaterial
. You can access the frame's texture and UV with a
sampler2D
using hint_screen_texture
and the built in SCREEN_UV
uniforms.
Copy the following code to your shader. The code below is a hex pixelization shader by arlez80,
shader_type canvas_item;
uniform vec2 size = vec2(32.0, 28.0);
uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_nearest;
void fragment() {
vec2 norm_size = size * SCREEN_PIXEL_SIZE;
bool half = mod(SCREEN_UV.y / 2.0, norm_size.y) / norm_size.y < 0.5;
vec2 uv = SCREEN_UV + vec2(norm_size.x * 0.5 *