Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // 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
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- #define INV_SQRT_OF_2PI 0.39894228040143267793994605993439 // 1.0/SQRT_OF_2PI
- #define INV_PI 0.31830988618379067153776752674503
- // 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 smartDeNoise(sampler2D tex, ivec2 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 / (2.0 * 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)
- vec4 centrPx = texelFetch(tex, uv, 0);
- float zBuff = 0.0;
- vec4 aBuff = vec4(0.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);
- float blurFactor = exp( -dot(d , d) * invSigmaQx2 ) * invSigmaQx2PI;
- vec4 walkPx = texelFetch(tex, uv+ivec2(x,y), 0);
- vec4 dC = walkPx-centrPx;
- float deltaFactor = exp( -dot(dC, dC) * invThresholdSqx2) * invThresholdSqrt2PI * blurFactor;
- zBuff += deltaFactor;
- aBuff += deltaFactor*walkPx;
- }
- }
- return aBuff/zBuff;
- }
- // About Standard Deviations (watch Gauss curve)
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- // kSigma = 1*sigma cover 68% of data
- // kSigma = 2*sigma cover 95% of data - but there are over 3 times
- // more points to compute
- // kSigma = 3*sigma cover 99.7% of data - but needs more than double
- // the calculations of 2*sigma
- // Optimizations (description)
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- // fX = exp( -(x*x) * invSigmaSqx2 ) * invSigmaxSqrt2PI;
- // fY = exp( -(y*y) * invSigmaSqx2 ) * invSigmaxSqrt2PI;
- // where...
- // invSigmaSqx2 = 1.0 / (sigma^2 * 2.0)
- // invSigmaxSqrt2PI = 1.0 / (sqrt(2 * PI) * sigma)
- //
- // now, fX*fY can be written in unique expression...
- //
- // e^(a*X) * e^(a*Y) * c*c
- //
- // where:
- // a = invSigmaSqx2, X = (x*x), Y = (y*y), c = invSigmaxSqrt2PI
- //
- // -[(x*x) * 1/(2 * sigma^2)] -[(y*y) * 1/(2 * sigma^2)]
- // e e
- // fX = ------------------------------- fY = -------------------------------
- // ________ ________
- // \/ 2 * PI * sigma \/ 2 * PI * sigma
- //
- // now with...
- // a = 1/(2 * sigma^2),
- // X = (x*x)
- // Y = (y*y) ________
- // c = 1 / \/ 2 * PI * sigma
- //
- // we have...
- // -[aX] -[aY]
- // fX = e * c; fY = e * c;
- //
- // and...
- // -[aX + aY] [2] -[a(X + Y)] [2]
- // fX*fY = e * c = e * c
- //
- // well...
- //
- // -[(x*x + y*y) * 1/(2 * sigma^2)]
- // e
- // fX*fY = --------------------------------------
- // [2]
- // 2 * PI * sigma
- //
- // now with assigned constants...
- //
- // invSigmaQx2 = 1/(2 * sigma^2)
- // invSigmaQx2PI = 1/(2 * PI * sigma^2) = invSigmaQx2 * INV_PI
- //
- // and the kernel vector
- //
- // k = vec2(x,y)
- //
- // we can write:
- //
- // fXY = exp( -dot(k,k) * invSigmaQx2) * invSigmaQx2PI
- //
- void mainImage( out vec4 fragColor, in vec2 fragCoord )
- {
- ivec2 texSize = textureSize(iChannel0, 0);
- vec2 invTexSize = 1.0 / vec2(texSize);
- ivec2 uv = ivec2(fragCoord) % texSize;
- float szSlide = 3.0;
- vec2 mouse = iMouse.xy;
- if(mouse.x <= 0.0 && mouse.y <= 0.0) mouse.x = iResolution.x / 2.0; // to show initial screen half splitted
- fragColor = fragCoord.x < mouse.x-szSlide ? texelFetch(iChannel0, uv, 0)
- : (fragCoord.x > mouse.x+szSlide ? smartDeNoise(iChannel0, uv, 5.0, 2.0, .100)
- : vec4(1.0));
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement