White noise shader on screen for Godot 4 ( and GLSL).
Film grain is one of the final effects that you apply to add a bit of stylized look or realism to your game. The slight imperfections it adds makes scene look more natural.
How it works?
Film grain is post processing screen space shader; which takes whole rendered scene as texture & applies grains to it.
The grains are just white noise. Their intensity & size can be adjusted. Additionally, we can generate animated noise for animated film grains.
Implementation
- Pass screen texture, grain size, amount, and other uniforms.
- Sample screen texture in fragment shader.
- Generate pseudo-random noise.
- Add noise to screen texture.
- Clamp the final color to keep it in range (0, 1) & apply to the fragment color.
The following implementation is for Godot 4; but the Godot shader language is almost same as GLSL.
Shader Code
shader_type canvas_item;
uniform sampler2D screen_texture : hint_screen_texture;
uniform float grain_amount : hint_range(0.0, 1.0) = 0.05; // Adjust the amount of grain
uniform float grain_size : hint_range(0.1, 10.0) = 1.0; // Adjust the size of the grain
uniform bool animate = false;
void fragment() {
// Sample the original screen texture
vec4 original_color = texture(screen_texture, SCREEN_UV);
float noise = 0.0;
if (animate) {
// Generate random noise
noise = (fract(sin(dot(UV * TIME, vec2(12.9898, 78.233))) * 43758.5453) - 0.5) * 2.0;
} else {
noise = (fract(sin(dot(UV, vec2(12.9898, 78.233))) * 43758.5453) - 0.5) * 2.0;
}
// Add noise to the original color
original_color.rgb += noise * grain_amount * grain_size;
// Clamp the final color to make sure it stays in the valid range
COLOR = clamp(original_color, 0.0, 1.0);
}