Go to bottom

blur edges in pixelshader

category: gfx [glöplog]
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?
added on the 2015-07-24 15:33:26 by motte motte
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.
added on the 2015-07-24 15:41:54 by Gargaj Gargaj
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; }
added on the 2015-07-24 16:31:11 by Soundy Soundy
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);
added on the 2015-07-24 16:42:41 by hornet hornet
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.
added on the 2015-07-24 19:06:00 by motte motte
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.
added on the 2016-04-05 18:33:27 by ollj ollj
@motte: This should do roughly what you want: https://www.shadertoy.com/view/XsXSz4
added on the 2016-04-05 18:54:53 by kusma kusma


Go to top