• Stars
    star
    247
  • Rank 164,117 (Top 4 %)
  • Language
    C++
  • License
    BSD 2-Clause "Sim...
  • Created about 5 years ago
  • Updated about 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Fast glsl deNoise spatial filter, with circular gaussian kernel, full configurable

glslSmartDeNoise

Fast glsl spatial deNoise filter, with circular gaussian kernel and smart/flexible/adaptable -> full configurable:

  • Standard Deviation sigma radius
  • K factor sigma coefficient
  • Edge sharpening threshold

*result depends on settings and input signal

Enhancements

Some enhancements can be obtained using "other color spaces" on noise evaluation (not on final image), to emphasize pixel differences/threshold.

  • sRGB with gamma correction.
  • Luminance
  • HSL using HL components and leaving out S (saturation)
  • ... other possibles (write me)

All this can lead to better results, under certain circumstances, but at the expense of performance, so these are not inserted in the main filter: use live WebGL demo to try they. *full source is provided in example folder - main filter variants are contained in Shaders/frag.glsl file

Live WebGL2 demo -> glslSmartDeNoise
Tree - Sunset
Runner - on the beach
Tree - Daylight

About live WebGL2 demos

You can run/test WebGL 2 examples of glslSmartDeNoise also from following links:

It works only on browsers with WebGl 2 and webAssembly support (FireFox/Opera/Chrome and Chromium based)

Test if your browser supports WebGL 2, here: WebGL2 Report

glslSmartDeNoise is used in glChAoS.P poroject to produce a effect like a "stardust" or "particle-dust" (it's the "bilinear threshold" filter in GLOW section) You can watch a graphical example at glChAoS.P glow threshold effect link

glslSmartDeNoise filter

Below there is the filter source code with parameters description: this is everything you need.

To view its use you can also examine the Shader\frag.glsl file (all other files are only part of the C++ examples)

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  Copyright (c) 2018-2019 Michele Morrone
//  All rights reserved.
//
//  https://michelemorrone.eu - https://BrutPitt.com
//
//  [email protected] - [email protected]
//  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, 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/(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;
}

Below there are considerations about parameters utilization and the optimizations description.

//  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
//

*can find it also in Shader/frag.glsl file

Building Example

The C++ example shown in the screenshot is provided. To build it you can use CMake (3.15 or higher) or the Visual Studio solution project (for VS 2017/2019) in Windows. You need to have installed GLFW (v.3.3 or above) in your compiler search path (LIB/INCLUDE). Other tools: ImGui, lodePNG and glad are attached, and already included in the project.

To build example with CMake in Linux / MacOS / Windows uses follow command:

# cmake -DBuildTarget:String=<BuildVer> -G <MakeTool> -B<FolderToBuild>
#   where:
#       <BuildVer> must be one of follow strings:
#           OpenGL_45
#           OpenGL_41
#           OpenGL_ES
#       <MakeTool> is your preferred generator like "Unix Makefiles" or "Ninja"
#       <FolderToBuild> is the folder where will be generated Makefile, move in it and run your generator
#       - Default build is "Release" but it can be changed via CMAKE_BUILD_TYPE definition:
#           command line: -DCMAKE_BUILD_TYPE:STRING=<Debug|Release|MinSizeRel|RelWithDebInfo>
#           cmake-gui: from combo associated to CMAKE_BUILD_TYPE var
#
# Example:
#   to build example compliant to OpenGL 4.5, with "make" utility, in "./build" folder, type:
#
#       > cmake -DBuildTarget:String=OpenGL_45 -G Unix\ Makefiles -B./build
#       > cd build
#       > make
#

The CMake file is able to build also an EMSCRIPTEN version, obviously you need to have installed EMSCRIPTEN SDK on your computer (1.38.10 or higher):

# To build example with EMSCRIPTEN uses follow command:
# cmake cmake -DCMAKE_TOOLCHAIN_FILE:STRING=<EMSDK_PATH>/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DBuildTarget:String=<BuildVer> -G "Unix Makefiles"|"ninja" -B<FolderToBuild>
#   where:
#       <EMSDK_PATH> is where was installed EMSCRIPTEN: you need to have it in EMSDK environment variable
#       <BuildVer> must be one of follow strings:
#           WebGL
#       <MakeTool> is your preferred generator like "Unix Makefiles" or "ninja"
#           Windows users need to use MinGW-make utility (by EMSCRIPTEN specification): ninja or othe can not work.
#       <FolderToBuild> is the folder where will be generated Makefile, move in it and run your generator
#       - Default build is "MinSizeRel" but it can be changed via CMAKE_BUILD_TYPE definition:
#           command line: -DCMAKE_BUILD_TYPE:STRING=<Debug|Release|MinSizeRel|RelWithDebInfo>
#           cmake-gui: from combo associated to CMAKE_BUILD_TYPE var

To build the EMSCRIPTEN version, in Windows, with CMake, need to have mingw32-make.exe in your computer and search PATH (only the make utility is enough): it is a condition of EMSDK tool to build with CMake in Windows.

More Repositories

1

glChAoS.P

3D GPUs Strange Attractors and Hypercomplex Fractals explorer - up to 256 Million particles in RealTime
C++
791
star
2

imGuIZMO.quat

ImGui GIZMO widget - 3D object manipulator / orientator
C++
383
star
3

virtualGizmo3D

Virtual GIZMO - 3D object manipulator / orientator, via mouse, with pan and dolly/zoom features
C++
45
star
4

fastPRNG

FAST 32/64 bit PRNG (pseudo-random generator), highly optimized, based on xoshiro* / xoroshiro*, xorshift and other Marsaglia algorithms.
C++
23
star
5

DLAf-optimized

Fast and slight DLA3D / DLA2D (Diffusion Limited Aggregation)
C++
18
star
6

wglMandelBulber

WebGL Ray Marching MandelBulber 3D rendering
JavaScript
12
star
7

vgMath

Math Library: vectors, quaternions, square Matrix, GLSL / HLSL alias types names, template or fixed types configurable
C++
11
star
8

glslCodeLite_lexers

Syntax highlighter lexer for GLSL (OpenGL Shading Language) to use with CodeLite cross platform IDE
5
star
9

PerlinNoise4D

Volumetric multi-threading (OpenMP) Perlin Noise 4D with OpenGL view
C
5
star
10

et4000.fractals

Olden fractals generator running using lowlevel (ASM) et4000 VideoCard and FPU programming, with full functional live/online DosBox demo
C
4
star
11

wglRayMarchedFractals

JavaScript
3
star
12

BorealStarryNight

WebGL virtual reconstruction of a boreal night landscape
GLSL
3
star
13

fastRandomGenerator

Single header, 32bit and 64bit FAST pseudo-random (fastrandom) generator, based on Marsaglia algorithms
C++
2
star
14

glslMandel

Very simple and short glsl Mandelbrot example
C
2
star
15

myRepos

It's a simple ScreenShots / LiveDemo container of mine repositories
JavaScript
1
star
16

rayMarching-glslNoise4D

Ray Marching on perlin noise 4D
C++
1
star