memononen / nanovg

Antialiased 2D vector drawing library on top of OpenGL for UI and visualizations.
zlib License
5.06k stars 767 forks source link

zero-height fill causes 1-pixel-width leak of overlapping strokes #589

Open jiandingzhe opened 3 years ago

jiandingzhe commented 3 years ago

The following drawing contains two overlapping strokes and one fill between them. Specifically, the fill contains a zero-height part where corresponding stroke is purely horizontal. As a result, there will have one-pixel-width leakage of previous stroke (green) on the latter one (red).

In addition:

jiandingzhe commented 3 years ago

Screenshot at 2020-10-09 17-50-13 part screenshot of rendering result

memononen commented 3 years ago

There are problems with very thin features due to anti-aliasing algorithm. It shrinks the shape by 0.5px, and on very thin features that may flip it inside out.

If you need to make the zero height to work, you need to MSAA, and turn off the software AA in nanovg.

jiandingzhe commented 3 years ago

After have some look on the rendering sequence provided by NSight, I found that the last OpenGL draw call in fill command attempts to do coloring and stencil buffer clear at the same time, but the geometry is one pixel-line smaller than the rendered stencil buffer in my example, thus stencil buffer is not fully cleared and disturbs subsequent rendering.

I tried to add an extra glClear(GL_STENCIL_BUFFER_BIT) call at last of glnvg__fill function. This ensure stencil buffer is clear and it really solves this rendering glitch. However I'm not going to pull-request this change, as it looks a little bit dirty and may reduce rendering speed to some extent.

I'm wondering if it's possible to generate stencil buffers in some nicer way (e.g. by some refined bit mode), so that previous remnants would always overwritten and not disturb new drawings?

xandramax commented 2 years ago

This antialiasing issue can also present itself when using NVG_HOLE path winding:

https://community.vcvrack.com/t/investigating-a-rendering-error-in-rack-2-nvg-hole-layer-1/14798