Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement blur filter with dual kawase technique #2821

Closed
gw3583 opened this issue Jun 17, 2018 · 8 comments
Closed

Implement blur filter with dual kawase technique #2821

gw3583 opened this issue Jun 17, 2018 · 8 comments

Comments

@gw3583
Copy link
Contributor

gw3583 commented Jun 17, 2018

See https://community.arm.com/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-26-50/siggraph2015_2D00_mmg_2D00_marius_2D00_notes.pdf for details of quality / performance improvements.

@pcwalton
Copy link
Contributor

I wrote a quick script to compare similarity of Gaussian blurs of various radii with various numbers of dual Kawase passes. Here are the results:

ssim between gaussian blur and dual kawase passes

@gw3583
Copy link
Contributor Author

gw3583 commented Aug 15, 2018

@pcwalton
Copy link
Contributor

pcwalton commented Aug 17, 2018

I did some experimentation and tentatively came up with the following formulas to determine suitable parameters for the dual Kawase blur:

numPasses = max(1, round(4/3 * log(blurRadius)))
distance = pow(0.4538, numPasses) * blurRadius

Experimentally, these parameters create blurs that are within 0.02 (i.e. 2%) SSIM of the reference Gaussian blur.

Note that with dual Kawase blurs, images tend to accumulate blocky artefacts if shrunk down too much. So after 4 downsample operations, I stop allocating smaller framebuffers. (That is, the size of each intermediate framebuffer is always at least 1/16 of the size of the original images.) Another way of thinking about this is it looks best to switch from a dual Kawase blur to a regular Kawase blur after 4 downsample operations, effectively forming a "partial dual Kawase blur".

@LifeIsStrange
Copy link

LifeIsStrange commented Aug 17, 2018

I don't know if it's helpful but you could maybe take a look at the openCV implémentation
https://docs.opencv.org/3.3.1/d4/d86/group__imgproc__filter.html#gaabe8c836e97159a9193fb0b11ac52cf1

Especially at the CUDA accelerated one (but could be open/sysCLised)
https://docs.opencv.org/2.4/modules/gpu/doc/image_filtering.html

@pcwalton
Copy link
Contributor

pcwalton commented Aug 25, 2018

Status update: I've come up with a "dual Gaussian" blur that is a variation on the dual Kawase technique based on Gaussian blur. Essentially I downsample, then upsample repeatedly, applying a 6x6 Gaussian kernel every time I upsample. (Thanks to the bilinear filtering hardware, this only requires 10 taps, which is slightly better than the 13 taps per level of dual Kawase.)

This results in images that are very similar to the full Gaussian blur, but there is an issue: when animating blur, discontinuities are visible when crossing over the threshold at which we introduce a new downsample/upsample pass. I tried to minimize it, but I'm a bit out of ideas at the moment as to how to eliminate it entirely. I'm not sure how much we care—on balance, I'd take making all blurs faster over perfectly smooth animated blurs—but it's a bit of a bummer.

@jrmuizel
Copy link
Collaborator

Do you have a video of the transitioning radius that you can share?

@pcwalton
Copy link
Contributor

pcwalton commented Aug 25, 2018 via email

pcwalton added a commit to pcwalton/webrender that referenced this issue Sep 5, 2018
… the

texture filtering hardware more effectively.

This new shader performs Gaussian *resampling* instead of regular convolution.
It samples in between texels to reduce the number of taps.

The speed is about the same as the existing technique. It is nevertheless the
fastest blur method that I could come up with. In particular, it exceeds the
performance of the Kawase and dual Kawase blur techniques. The speed comes from
working at lower resolution and incurring fewer downsampling and upsampling
passes. As is often the case, ALU performance does not really seem to be the
limiting factor; it's mostly memory bandwidth, which is why downsampling is so
important. Further improvements should come from not doing the downsampling at
all and instead rendering the blurred content at low resolution to begin with.

Closes servo#2821.
pcwalton added a commit to pcwalton/webrender that referenced this issue Sep 6, 2018
… the

texture filtering hardware more effectively.

This new shader performs Gaussian *resampling* instead of regular convolution.
It samples in between texels to reduce the number of taps.

The speed is about the same as the existing technique. It is nevertheless the
fastest blur method that I could come up with. In particular, it exceeds the
performance of the Kawase and dual Kawase blur techniques. The speed comes from
working at lower resolution and incurring fewer downsampling and upsampling
passes. As is often the case, ALU performance does not really seem to be the
limiting factor; it's mostly memory bandwidth, which is why downsampling is so
important. Further improvements should come from not doing the downsampling at
all and instead rendering the blurred content at low resolution to begin with.

Closes servo#2821.
pcwalton added a commit to pcwalton/webrender that referenced this issue Sep 6, 2018
… the

texture filtering hardware more effectively.

This new shader performs Gaussian *resampling* instead of regular convolution.
It samples in between texels to reduce the number of taps.

The speed is about the same as the existing technique. It is nevertheless the
fastest blur method that I could come up with. In particular, it exceeds the
performance of the Kawase and dual Kawase blur techniques. The speed comes from
working at lower resolution and incurring fewer downsampling and upsampling
passes. As is often the case, ALU performance does not really seem to be the
limiting factor; it's mostly memory bandwidth, which is why downsampling is so
important. Further improvements should come from not doing the downsampling at
all and instead rendering the blurred content at low resolution to begin with.

Closes servo#2821.
@gw3583
Copy link
Contributor Author

gw3583 commented Feb 4, 2019

We investigated this and determined it's not a viable technique for what we need, due to performance / quality concerns. @pcwalton can provide more detail if anyone's is interested in the gory details.

@gw3583 gw3583 closed this as completed Feb 4, 2019
kdrag0n added a commit to ProtonAOSP/android_frameworks_native that referenced this issue Apr 4, 2021
This is an implementation of dual-filter Kawase blur [1], with many
optimizations and quality tweaks.

It was NOT shipped in any ProtonAOSP releases due to some problems with
the smooth radius transitions typically used in mobile UIs. This is an
inherent problem with the blur algorithm; see the Servo issue [2] for
more details.

The source code has been made for reference purposes, but it is not
meant for production use.

[1] https://community.arm.com/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-26-50/siggraph2015_2D00_mmg_2D00_marius_2D00_notes.pdf
[2] servo/webrender#2821

Change-Id: I5a774f2b55140860f82ac5e6fb4400f20aed8d81
kdrag0n added a commit to ProtonAOSP/android_frameworks_native that referenced this issue Apr 4, 2021
This is an implementation of dual-filter Kawase blur [1], with many
optimizations and quality tweaks.

It was NOT shipped in any ProtonAOSP releases due to some problems with
the smooth radius transitions typically used in mobile UIs. This is an
inherent problem with the blur algorithm; see the Servo issue [2] for
more details.

The source code has been made for reference purposes, but it is not
meant for production use.

Because this blur implementation was never formally released, the commit
messages and history are messy as they are from my quick iteration
workflow during early development. All commits were preserved for
reference, but they are not representative of my production-ready
commits.

[1] https://community.arm.com/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-26-50/siggraph2015_2D00_mmg_2D00_marius_2D00_notes.pdf
[2] servo/webrender#2821

Change-Id: I5a774f2b55140860f82ac5e6fb4400f20aed8d81
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants