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

3D fire shader

Ray marching ocean waves + atmosphere

screen space refraction shader

Related shaders

Post-Processing, Grain PP effect and Palette Color

Grain (Old Movie)

Blood Shader

Subscribe
Notify of
guest

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Pedro Silva
6 months 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!