added optimized-bilateral-filter
This commit is contained in:
parent
c4d3854b27
commit
c4db79de74
|
@ -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);
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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.
|
Loading…
Reference in New Issue