81 lines
2.7 KiB
GLSL
81 lines
2.7 KiB
GLSL
|
|
#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);
|
|
}
|