Gaussian blur5/21/2023 ![]() The results for the standard Gaussian and the optimized one were identical: Pixel Position I did so by blurring a one-pixel wide value of 1.0 using a blur with a 9 pixel area (a 4 pixel radius) and a sigma (blur strength) of 1.83. To convince myself of this, I took Daniel's weighting equations and compared them to standard Gaussian weights. You get this interpolation for free, and it turns out that if you read from just the right position between the pixels for a Gaussian blur and adjust the weights to match, you get the exact same results as if you had read and weighted each of the pixels individually. When you have linear interpolation enabled for a texture in OpenGL, if you read anywhere between two pixels, you get back a weighted average of those two values. The second large optimization, as described by Daniel Rákos in his great article on the subject, is to use hardware interpolation on the GPU to nearly halve the number of operations. This means that for our example of a 9-pixel-diameter blur, you go from 81 operations per pixel to two passes of 9 operations (for a total of 18). That is, rather than blurring in both X and Y at once, you can first blur in one direction, and then the other. ![]() The first relies on the fact that a Gaussian blur is a separable operation. To this end, there are two significant optimizations that can be made to a Gaussian blur on the GPU. One of these rules is that you should minimize the number of pixels you read within a given fragment shader, and a closely related one is that you should minimize the number of calculations performed within one. Optimizing these shaders can be more of an art than a science sometimes, but there are some general rules to follow. Reducing the number of texture readsĪs mentioned, a blur like this can performed using a fragment shader, a small C-like program that is used by the GPU to perform operations on every fragment (pixel) of an input texture (image). With the proper use of a fragment shader, these blurs can be done much faster than on the CPU, but even there optimizations are needed to make these fast. Thankfully, GPUs are built to do parallel operations like this. This grows as a square of the strength of your blur, so you can see how this can add up to a lot of computation per blurred image. For a Gaussian blur that acts over an area 9 pixels in diameter, you're looking at 81 pixels that need to be read, weighted, and summed for every single pixel in your input image. How a Gaussian blur worksĪ Gaussian blur works by sampling the color values of pixels in a radius around a central pixel, then applying a weight to each of these colors based on a Gaussian distribution function:Īs the radius of a Gaussian blur grows, it quickly becomes an extremely expensive operation. At higher blur radii, I'm slower than Core Image, though, and I don't quite understand why. I've completely rewritten this Gaussian blur, and it now supports arbitrary blur radii while still being tuned for the iOS GPUs. ![]() GPUImage has had a reasonably performant, but somewhat limited Gaussian blur implementation for a while, but I've not been happy with it. With the launch of iOS 7, and its use of blurs throughout the interface, there's been a lot of interest in fast ways of blurring content.
0 Comments
Leave a Reply. |