From c4db79de74e60668eac9ea31d97a398f1e9d5df8 Mon Sep 17 00:00:00 2001 From: teridax Date: Sat, 3 Jun 2023 16:58:20 +0200 Subject: [PATCH] added optimized-bilateral-filter --- Optimized-Bilateral-Filter/Buffer A.glsl | 32 +++++++++++ Optimized-Bilateral-Filter/Image.glsl | 71 ++++++++++++++++++++++++ Optimized-Bilateral-Filter/README.md | 9 +++ 3 files changed, 112 insertions(+) create mode 100644 Optimized-Bilateral-Filter/Buffer A.glsl create mode 100644 Optimized-Bilateral-Filter/Image.glsl create mode 100644 Optimized-Bilateral-Filter/README.md diff --git a/Optimized-Bilateral-Filter/Buffer A.glsl b/Optimized-Bilateral-Filter/Buffer A.glsl new file mode 100644 index 0000000..a1e6bee --- /dev/null +++ b/Optimized-Bilateral-Filter/Buffer A.glsl @@ -0,0 +1,32 @@ + +float luminance(in vec3 srgb) +{ + return dot(srgb, vec3(0.2126, 0.7152, 0.0722)); +} + +float falloff(in float lum) +{ + float sq = lum * lum; + return sq * sq - 2.0 * sq + 1.0; +} + +vec3 mix_with_noise(inout vec3 col, in vec2 uv) +{ + vec3 noise = texture(iChannel1, uv).rgb; + + float fac = falloff(luminance(col) * 2.0 - 1.0); + + return mix(col, noise, fac * 0.2); +} + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + vec2 uv = fragCoord/iResolution.xy; + + vec3 imageCol = texture(iChannel0, uv).rgb; + + vec3 col = mix_with_noise(imageCol, uv * 2.0); + col = mix_with_noise(col, uv * 0.5); + + fragColor = vec4(col, 1.0); +} diff --git a/Optimized-Bilateral-Filter/Image.glsl b/Optimized-Bilateral-Filter/Image.glsl new file mode 100644 index 0000000..65f5d74 --- /dev/null +++ b/Optimized-Bilateral-Filter/Image.glsl @@ -0,0 +1,71 @@ +float tentKernel(in vec2 xy, in float r) +{ + return (1.0 - abs(xy.x/r)) * (1.0 - abs(xy.y/r)) / (r*r); +} + +float gaussianWeight(in float delta, in float sigma) +{ + return exp(-delta*delta/(2.0 * sigma * sigma)) * 2.5 * sigma; +} + +float luminance(in vec3 col) +{ + return dot(col, vec3(0.2126, 0.7152, 0.0722)); +} + +vec3 fasterBilateralFilter(in vec2 uv, in sampler2D tex, in int r, in int steping, in float omegaColor) +{ + vec2 scale = 1.0 / vec2(textureSize(tex, 0)); + + vec3 sum = vec3(0); + + vec3 original = texture(tex, uv).rgb; + + float wp = 0.0; + + for (int x = -r; x <= r; x+=steping) + for (int y = -r; y <= r; y+=steping) + { + vec2 off = vec2(x, y) * scale; + + vec3 col = texture(tex, uv + off).rgb; + + float di = luminance(original) - luminance(col); + float space = tentKernel(vec2(x, y), float(r)); + float range = gaussianWeight(di, omegaColor); + float w = space * range; + + wp += w; + + sum += col * w; + } + + return sum / wp; +} + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + vec2 uv = fragCoord/iResolution.xy; + + vec3 col; + + if (uv.x < 0.33333) + { + col = texture(iChannel0, uv).rgb; + } + else if (uv.x > 0.33333 && uv.x < 0.66666) + { + col = fasterBilateralFilter(uv, iChannel0, 12, 3, 0.1); + } + else + { + col = texture(iChannel1, uv).rgb; + } + + const float PI = 3.141592653589793; + float border = step(0.02, abs(sin(uv.x*PI*3.0))); + + col *= border; + + fragColor = vec4(col,1.0); +} diff --git a/Optimized-Bilateral-Filter/README.md b/Optimized-Bilateral-Filter/README.md new file mode 100644 index 0000000..a2e84a0 --- /dev/null +++ b/Optimized-Bilateral-Filter/README.md @@ -0,0 +1,9 @@ +# Optimized-Bilateral-Filter +A biliteral filter is essentially a gaussian blur filter with an extra weight applied per pixel. +This weight is a the luminance range between the target pixel to filter and the sourounding pixels passed into +a gaussian weight function. + +# Optimization +Instead of applying a very costly gaussian blur filter we can optimize it by using a tent blur filter instead. +This allows to speed up the performance by replacing the gaussian weight function with a tent blur kernel. +Additionally we can optimize the squareroot of the gaussian weight function for the luminance range away.