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); //} // Feel free to steal this :^) // Consider it MIT licensed, you can link to this page if you want to. #define SHOW_NOISE 0 #define SRGB 0 // 0: Addition, 1: Screen, 2: Overlay, 3: Soft Light, 4: Lighten-Only #define BLEND_MODE 4 #define SPEED 1.0 #define INTENSITY 0.05 // What gray level noise should tend to. #define MEAN 0.0 // Controls the contrast/variance of noise. #define VARIANCE 0.5 vec3 channel_mix(vec3 a, vec3 b, vec3 w) { return vec3(mix(a.r, b.r, w.r), mix(a.g, b.g, w.g), mix(a.b, b.b, w.b)); } float gaussian(float z, float u, float o) { return (1.0 / (o * sqrt(2.0 * 3.1415))) * exp(-(((z - u) * (z - u)) / (2.0 * (o * o)))); } vec3 madd(vec3 a, vec3 b, float w) { return a + a * b * w; } vec3 screen(vec3 a, vec3 b, float w) { return mix(a, vec3(1.0) - (vec3(1.0) - a) * (vec3(1.0) - b), w); } vec3 overlay(vec3 a, vec3 b, float w) { return mix(a, channel_mix( 2.0 * a * b, vec3(1.0) - 2.0 * (vec3(1.0) - a) * (vec3(1.0) - b), step(vec3(0.5), a) ), w); } vec3 soft_light(vec3 a, vec3 b, float w) { return mix(a, pow(a, pow(vec3(2.0), 2.0 * (vec3(0.5) - b))), w); } void fragment() { vec2 ps = vec2(1.0) / (1.0 / SCREEN_PIXEL_SIZE).xy; vec2 uv = SCREEN_UV; //coord * ps; COLOR = texture(screen_texture, uv); #if SRGB color = pow(color, vec4(2.2)); #endif float t = TIME * float(SPEED); float seed = dot(uv, vec2(12.9898, 78.233)); float noise = fract(sin(seed) * 43758.5453 + t); noise = gaussian(noise, float(MEAN), float(VARIANCE) * float(VARIANCE)); #if SHOW_NOISE COLOR = vec4(noise); #else // Ignore these mouse stuff if you're porting this // and just use an arbitrary intensity value. float w = float(INTENSITY); vec3 grain = vec3(noise) * (1.0 - COLOR.rgb); #if BLEND_MODE == 0 COLOR.rgb += grain * w; #elif BLEND_MODE == 1 COLOR.rgb = screen(COLOR.rgb, grain, w); #elif BLEND_MODE == 2 COLOR.rgb = overlay(COLOR.rgb, grain, w); #elif BLEND_MODE == 3 COLOR.rgb = soft_light(COLOR.rgb, grain, w); #elif BLEND_MODE == 4 COLOR.rgb = max(COLOR.rgb, grain * w); #endif #if SRGB COLOR = pow(COLOR, vec4(1.0 / 2.2)); #endif #endif }