-
Notifications
You must be signed in to change notification settings - Fork 767
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
removing discard from the fragment shader significantly improves performance on iOS #214
Comments
It should be possible to set the alpha value to 0.0 instead of using discard to make the pixel completely transparent. Discard is indeed an issue on many mobile configurations, so this should likely be done for all OpenGL ES configurations. |
@dougbinks, setting the alpha to 0.0 doesn't fix the artifacts. In fact it creates a new problem with strokes: I did the following:
|
The blend function is glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); so this is likely due to depth or stencil testing issues and so not easily solvable though Mikko might be able to come up with a solution. Since the discard is only on the EDGE_AA path, I would not use the NVG_ANTIALIAS if you want performance. |
Good thought about the stenciling. Turning off NVG_STENCIL_STROKES gets rid of the artifacts, but of course then self-intersecting paths are drawn differently (which I can live with). |
Good catch! I wonder if splitting the shaders would make it faster on mobile too? So that if one shader uses discard, all shaders don't pay the penalty? The idea of the discard is that we first draw the "fill" of the stroke, but only once, and then on second pass we draw the AA bit of the stroke. It either needs two sets of geometry, or discard/alphatest. I chose to use discard. |
Splitting the shaders may help, since the discard is driven by data it can't be optimized out and tile based GPUs then pay a big penalty (there's a cost too on other GPUs, but it's far less). |
If two AA parts of a path each mostly cover a pixel, would the color be computed as if coverage is greater than the area of the pixel? I'm trying to understand the existing implementation. |
The AA in nanovg works so that first the solid (non-AA) part of the shape is drawn, creating a stencil mask of the fill of the shape. Then the solid shape is filled using a quad. Finally, the stencil test is inverted, and an antialiased line is drawn around the perimeter (since AA-line drawing is iffy, this line is created as a triangle strip). The stencil mask is also used to handle the fill rule of the shape so that you can have holes. The That means that with both methods, the AA edge (I call it AA-fringe) can be slightly wrong, as it will be overdrawn in case the shape intersects or overaps. You can see this sometimes especially with light colors, but generally it works well. You can also configure NanoVG to not generate any of the AA fringes and set your frame buffer to use multisampling AA (i.e. MSAA) if correct coverage is required. |
I think you could draw the entire stroke in a single pass (with stenciling). Instead of overdraw of self-intersecting AA edges, you'd have underdraw. Would that work? |
If you draw the entire stroke with stencil in single pass you'll get the artifacts as in your first screenshots. That light line is the anti-aliased bit of the vertical segment, which happens to be drawn first. |
Ah, of course! Well, at least it seems like the discard isn't needed when |
That's correct. |
As discussed in memononen#214, the `discard` is not needed when `NVG_STENCIL_STROKES` is off. This commit follows the rule to deliver the best performance whenever possible.
Discard can be slow with some GPUs so avoid it when NVG_STENCIL_STROKES is not set. This patch is basically the same as in NanoVG issue memononen#214.
Before:
After:
I did notice some rendering artifacts for self-intersecting paths:
vs.
How should I fix the artifacts? Should there be an option exposed to turn off discard (it's a no-no on iOS)?
(I'm running the nanovg demo: https://github.com/wtholliday/nanovg-ios-demo)
The text was updated successfully, but these errors were encountered: