#define DENOISE #define FILM_GRAIN //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Copyright (c) 2018-2019 Michele Morrone // All rights reserved. // // https://michelemorrone.eu - https://BrutPitt.com // // me@michelemorrone.eu - brutpitt@gmail.com // twitter: @BrutPitt - github: BrutPitt // // https://github.com/BrutPitt/glslSmartDeNoise/ // // This software is distributed under the terms of the BSD 2-Clause license //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // smartDeNoise - parameters //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // sampler2D tex - sampler image / texture // vec2 uv - actual fragment coord // float sigma > 0 - sigma Standard Deviation // float kSigma >= 0 - sigma coefficient // kSigma * sigma --> radius of the circular kernel // float threshold - edge sharpening threshold vec4 smart_de_noise(in sampler2D tex, vec2 uv, float sigma, float kSigma, float threshold) { float radius = round(kSigma*sigma); float radQ = radius * radius; float invSigmaQx2 = 0.5 / (sigma * sigma); // 1.0 / (sigma^2 * 2.0) float invSigmaQx2PI = INV_PI * invSigmaQx2; // 1/(2 * PI * sigma^2) float invThresholdSqx2 = .5 / (threshold * threshold); // 1.0 / (sigma^2 * 2.0) float invThresholdSqrt2PI = INV_SQRT_OF_2PI / threshold; // 1.0 / (sqrt(2*PI) * sigma^2) vec4 centrPx = texture(tex,uv); float zBuff = 0.0; vec4 aBuff = vec4(0.0); vec2 size = vec2(textureSize(tex, 0)); vec2 d; for (d.x=-radius; d.x <= radius; d.x++) { float pt = sqrt(radQ-d.x*d.x); // pt = yRadius: have circular trend for (d.y=-pt; d.y <= pt; d.y++) { float blurFactor = exp( -dot(d , d) * invSigmaQx2 ) * invSigmaQx2PI; vec4 walkPx = texture(tex,uv+d/size); vec4 dC = walkPx-centrPx; float deltaFactor = exp( -dot(dC, dC) * invThresholdSqx2) * invThresholdSqrt2PI * blurFactor; zBuff += deltaFactor; aBuff += deltaFactor*walkPx; } } return aBuff/zBuff; } void mainImage( out vec4 fragColor, in vec2 fragCoord ) { init_random_state(fragCoord.xy, iTime); #ifdef DENOISE vec3 col = smart_de_noise(iChannel0, fragCoord/iResolution.xy, 10.0, 1.0, 0.2).rgb; #else vec3 col = texture(iChannel0, fragCoord/iResolution.xy).rgb; #endif #ifdef FILM_GRAIN float strength = 0.4; vec3 noise = vec3(gold_noise(), gold_noise(), gold_noise()); col = pow(col, noise * strength + 1.0) + pow(noise, vec3(strength)) * strength * 0.5; #endif fragColor = vec4(col, 1.0); }