QuantumBadger / Speedy2D

Rust library for hardware accelerated drawing of 2D shapes, images, and text, with an easy to use API.
Apache License 2.0
387 stars 42 forks source link

Support for Anti Aliasing on platforms where MSAA is unavailable #21

Open wyhinton opened 3 years ago

wyhinton commented 3 years ago

Hello!

Just wondering, are their any plans for implementing anti-aliasing drawing (FXAA, MLAA, or MSAA)? Right now drawing rounded shapes or angled lines displays the characteristically jagged lines you get without anti-aliasing.

Besides writing custom draw functions that implement things like feathering, is there any "out of the box" solution for AA when using Speedy2d?

Doing some more research on the topic I found someone's FXAA implementation for glium. Speedy2d uses glow for its GL backend, is that correct? Would it be hard to port this solution from glium to glow?

QuantumBadger commented 3 years ago

Thanks for raising this! By default Speedy2D uses MSAA (multisampling) x16. This is configurable using WindowCreationOptions::with_multisampling().

Unfortunately there are a lot of platforms which don't support this, for example I think a lot of Intel cards will ignore this setting.

It should be possible to add FXAA (or similar) support. My understanding is that FXAA involves drawing the image to an off-screen framebuffer, and then, while rendering that image to the screen, applying a blur to each pixel proportional to how "contrasty" the surrounding area is.

https://en.wikipedia.org/wiki/Fast_approximate_anti-aliasing

This could have undesirable effects on things like UI elements, image contents, and text, as these would have a blur applied to them.

Another option I was considering, for circles in particular, was the following method:

https://rubendv.be/posts/fwidth/

This would add some complexity to the fragment shader, but would only smooth circles, not lines or rectangle edges.

Ideally we'd use SSAA (render the framebuffer much larger than necessary, and then scale it down), which would produce results similar to MSAA. However this is extremely expensive, e.g. for a 4K screen you could end up rendering at 16K+, which would destroy performance.

So unfortunately I don't think there's an easy option for doing this efficiently and visually appealingly on all platforms. FXAA is something I'd be happy to have in Speedy2D, but it would have to be off by default and come with a list of caveats :)