|
|
|
|
Reply From: |
Zylann |
This shader blurs using a 3x3-pixel averaging filter (9 texscreens in a square pattern), like, it filters only in a radius of 1. If you want to blur a larger radius, you need a bigger filter (so a 5x5 filter for radius of 3, 7x7 filter for radius of 5 etc).
Problem is, you cannot just add zillions of texture fetches by making the filter bigger, because it will make your shader terribly expensive in a somewhat exponential way.
There is a nice property of such a filter system though: applying it multiple times will blur more, and adding more steps requires more GPU at a linear cost rather than “exponential” cost.
Unfortunately, I don’t know how to apply the same screen shader multiple times, maybe using several BackBufferCopy
nodes?
You can also complement your shader by rendering the blurred thing to a downscaled texture, and render that texture with filter enabled, which will add a cheap linear smoothing on top of your blur. It won’t be as accurate as a blur you would get in an image processing program, but it should look good enough for a game.
(Also note that Godot 3.0 uses similar techniques to render bloom and depth-of-field).
Another performance tip: usually you can blur by fetching only 4 pixels in a “+” pattern rather than all 9 pixels. It is a bit less accurate but the difference won’t be much noticeable, and you’ll double performance of your shader.
Hello. Do you know where I could get a code snippet for such a blur? Because I understand what you are saying but i dont know how to apply it, since i dont understand the shading language.
Taking your own code snippet and removing some lines, you get a cross-blur shader:
float radius = 0.009; // Note: do you understand what this radius actually is?
float divider = 4.0; // reduced this to 4 because we fetch 4 pixels
vec3 col = vec3(0);
col+= texscreen(SCREEN_UV+vec2(radius,0));
col+= texscreen(SCREEN_UV+vec2(-radius,0));
col+= texscreen(SCREEN_UV+vec2(0,-radius));
col+= texscreen(SCREEN_UV+vec2(0,radius));
col/=divider;
COLOR.rgb=col;
But this blur performs great only if you fetch neighbor pixels, not an arbitrary radius, otherwise it won’t look great.
Unfortunately I don’t know how to easily apply this shader multiple times or downscale its input…
Zylann | 2017-12-08 19:10
float radius = 0.009; // Note: do you understand what this radius actually is?
No I don’t really know what it does. I also don’t know how to apply a shader multiple times. I’ve tried multiplying the material and applying it, but that didn’t work.
My project is on Godot 2. Can I easily transfer my project, without everything corrupting or crashing? And isnt’t 3.0 very instable?
Godot 3.0 is in beta 1, it’s not ready yet for production but it does have more flexible ways to blur the screen like you want. The best way to migrate is to do a big review on all your project though, there is a converted worked on in 2.1.4 but it doesn’t do everything.
In 2.1 I don’t know more about blurring (at least in 2D)
Zylann | 2017-12-08 20:12
Ok, anyway, thanks for your help