blur edges in pixelshader
category: gfx [glöplog]
hi,
im working on a small pixelshader effect, where some triangles should have blurred edges.
wip: https://www.shadertoy.com/view/MtsSzB
now the edges of those triangles should have blurred edges.
i could just measure the distance of each pixel to that edge and blur accordingly, but that would use a couple of sqrts and i am afraid it affects performance.
is there an easier way to do this?
im working on a small pixelshader effect, where some triangles should have blurred edges.
wip: https://www.shadertoy.com/view/MtsSzB
now the edges of those triangles should have blurred edges.
i could just measure the distance of each pixel to that edge and blur accordingly, but that would use a couple of sqrts and i am afraid it affects performance.
is there an easier way to do this?
I don't think you need an actual distance calculation, you can always take Y as granted and just test for horizontal distance in X.
One lazy solution is to perform a deltaColor vertical blur (edge means the color changes), but I'm not sure it won't hit performance if many iterations are performed. Try pasting this in your shadertoy:
Code:
float calc1tri(float c, vec2 uv, int i, float ydecal)
{
vec2 p = getTriPoint(float(i));
vec2 left = vec2(-p.x+0.5, p.y-ydecal);
vec2 right = vec2(p.x+0.5, p.y-ydecal);
if (PointInTriangle(uv, right, left, vec2(0.5,0.0) ))
{
float distanceToEdge = length(uv-left);
float d = clamp(distanceToEdge, 0.0, 1.0);
c += 0.081;
}
return c;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy / iResolution.xy;
float c = 0.0;
float c2 = 0.0;
const int halfIterCount = 5;
for (int i=0;i<11;i++)
{
c2=0.0;
c = calc1tri(c, uv, i, 0.0);
float localc = c;
for (int j=-halfIterCount;j<halfIterCount;j++)
{
float fj = float(j);
localc = calc1tri(localc, uv, i, fj/iResolution.y);
c2 += max(0.0,localc-c); // delta color: take in account only if different from original color
}
c += c2/float(halfIterCount*2);
}
float lum = c/float(halfIterCount*2);
fragColor = vec4(0.98,0.7,0.5,1.0) + lum;
}
Lazier solution! ;D
Code:
for (int i=0;i<7;i++)
{
vec2 p = getTriPoint(float(i)*0.9);
vec2 left = vec2(-p.x+0.5, p.y);
vec2 right = vec2(p.x+0.5, p.y);
for (int j=0; j<16; ++j )
{
for ( int k=0; k<16; ++k )
{
vec2 uv2 = uv + vec2( j, k ) / iResolution.xy;
if (PointInTriangle(uv2, right, left, vec2(0.5,0.0) ))
{
float distanceToEdge = length(uv2-left);
float d = clamp(distanceToEdge, 0.0, 1.0);
c += 0.081;
}
}
}
}
c /= (16.0*16.0);
thanks guys!
@Gargaj: but that would only blur in one direction. they should be blurred in both.
@Soundy: thats a pretty much what i was going for. and performance seems also good!
@hornet: looks also cool, but the double for loop is an impact on performance.
@Gargaj: but that would only blur in one direction. they should be blurred in both.
@Soundy: thats a pretty much what i was going for. and performance seems also good!
@hornet: looks also cool, but the double for loop is an impact on performance.
Get depth zbuffer. Use filter that measures local contrast of zfuffer. Bilinear can already be good enough
. Blur with linear function of The filtered Image. Dumb but a simple parallel pipe may sometimes be faster.
. Blur with linear function of The filtered Image. Dumb but a simple parallel pipe may sometimes be faster.
@motte: This should do roughly what you want: https://www.shadertoy.com/view/XsXSz4