Film Grain Shader

Full code for the film grain shader tutorial that I wrote. The details of how to implement this shader are discussed in the post. If you simply need the code, its yours & no need for any credit!

Shader code
shader_type canvas_item;

// Uniforms
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

void fragment() {
    // Sample the original screen texture
    vec4 original_color = texture(screen_texture, SCREEN_UV);

    // Generate random noise
    float 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);
}
Tags
film grain, white noise
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from mujtaba-io

Fireball or Candle fire shader

Gerstner Wave Ocean Shader

3D fire shader

Related shaders

Grain (Old Movie)

Post-Processing, Grain PP effect and Palette Color

Topdown wind shader

Subscribe
Notify of
guest

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Pedro Silva
1 month ago

Hi there! I was checking your shader today (which I found thanks to @passivestar) and it worked out of the box.

Thanks for the contribution!

As the image I am working is very static (a 2D scene of a city), I decided to add a time changing element to the grains, by changing one line to:

float noise = (fract(sin(dot(UV, vec2(12.9898, 78.233))) * round(TIME*20.0) *8.5453) – 0.5) *1.5;

I imagine the possibilities of further customization are infinite…

Cheers!