//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 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 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef _DENOISE_GLSL_ #define _DENOISE_GLSL_ #define INV_SQRT_OF_2PI 0.39894228040143267793994605993439 #define INV_PI 0.31830988618379067153776752674503 vec4 smartDeNoise(sampler2D tex, vec2 uv, float sigma, float kSigma, float threshold) { float radius = round(kSigma*sigma); float radQ = radius * radius; float invSigmaQx2 = .5 / (sigma * sigma); // 1.0 / (sigma^2 * 2.0) float invSigmaQx2PI = INV_PI * invSigmaQx2; // 1.0 / (sqrt(PI) * sigma) float invThresholdSqx2 = .5 / (threshold * threshold); // 1.0 / (sigma^2 * 2.0) float invThresholdSqrt2PI = INV_SQRT_OF_2PI / threshold; // 1.0 / (sqrt(2*PI) * sigma) vec4 centrPx = texture(tex,uv); float zBuff = 0.0; vec4 aBuff = vec4(0.0); vec2 size = vec2(textureSize(tex, 0)); for(float x=-radius; x <= radius; x++) { float pt = sqrt(radQ-x*x); // pt = yRadius: have circular trend for(float y=-pt; y <= pt; y++) { vec2 d = vec2(x,y)/size; float blurFactor = exp( -dot(d , d) * invSigmaQx2 ) * invSigmaQx2; vec4 walkPx = texture(tex,uv+d); vec4 dC = walkPx-centrPx; float deltaFactor = exp( -dot(dC, dC) * invThresholdSqx2) * invThresholdSqrt2PI * blurFactor; zBuff += deltaFactor; aBuff += deltaFactor*walkPx; } } return aBuff/zBuff; } #endif