0

Currently, I'm implementing blur filter using opengl in Android. The blur filter is implemented through the shadertoy site. Adjust the Size value using the source below to apply blur properly. enter image description here

However, if you apply that source to Android, it is because you created a lot of texture2D It works well on some phones, but fps drops a lot on certain phones.

So, I changed the source to use the convolution kernel as follows. After changing, fps did not drop. enter image description here

Increasing the offset value slightly blurs, but if you increase the value gradually, A phenomenon that spreads as shown in the picture appears. How can a natural blur work like the first picture using the convolution kernel?

And where can I adjust the blur value?

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
Woodong
  • 51
  • 3
  • Do you understand why your shader creates this phenomenon? – user253751 Jun 30 '20 at 11:03
  • Also do you understand how blurring works? – user253751 Jun 30 '20 at 11:05
  • That's not how blurring kernel is usually done. But it does exactly what you told it do - gather pixels from `offset` units far away and add them. This does not control the blurriness, to do that you have to increase the kernel size. Use gaussian blur, it can be implemented as two pass 1D kernels, avoiding quadratic number of texture lookups. Nice tutorial is [here](https://learnopengl.com/Advanced-Lighting/Bloom). – Quimby Jun 30 '20 at 12:04

1 Answers1

1

Blur works by displaying the same texture at slightly different positions, which overlap itself. Their shader does this. Your shader does it too.

But to make a proper blurring effect, you need a lot of different positions - basically one per pixel distance that you want to blur. If you want to blur by 5 pixels, you need positions 0, 1, 2, 3, 4 and 5. Not just 0 and 5, or it will look like two overlapping copies of the texture, not like a blur. They're usually weighted, too, so that position 0 is strongest and position 5 is weakest.

You might be able to get away with skipping some - maybe you do 0,1,3,5 - but you can't skip all the way to the end and expect it to look good.

Your code only displays the texture at positions -5 and 0 and 5 (but in 2D, so it's actually -5,-5 and -5,0 and -5,5 and 0,-5 and 0,0 and 0,5 and 5,-5 and 5,0 and 5,5) but not all the in-between ones. This is why your result looks like 9 overlapping copies of the texture, and not like a blur.

5 pixels is a made-up number here for the sake of explanation. In your actual picture, it looks like about 20 pixels horizontally and 10 pixels vertically.

To get a blur, you need to sample all the in-between points. Which means that you need to use texture2D more than just 9 times. Which your original shader did, and your new shader does not.


Now, the Gaussian blur is a separable blur function. This means there is a very simple trick to making it fast. If you want a Gaussian blur, you simply do a vertical Gaussian blur, save that picture, and then do a horizontal Gaussian blur (or you can do horizontal first, it doesn't matter). This way, if you want a 20-pixel blur, you only have to sample 20 times and then another 20 times, instead of 400 times.

user253751
  • 57,427
  • 7
  • 48
  • 90