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

Artefacts appear when filled polygons are added to a plot #36

Open
berke opened this issue Jul 31, 2024 · 11 comments
Open

Artefacts appear when filled polygons are added to a plot #36

berke opened this issue Jul 31, 2024 · 11 comments
Labels
bug Something isn't working

Comments

@berke
Copy link

berke commented Jul 31, 2024

Filled polygons added to a plot show line-shaped artefacts under certain zooming conditions.

I have an eframe::App containing a canvas containing a Plot, where I draw filled triangles using ui.polygon.

For certain triangles and at certain zoom levels, this produces fill-colored linear artefacts.

No artefacts appear if the triangles are not filled.

To Reproduce

  1. Checkout https://github.com/berke/egui_triangle_bug
  2. Compile and run
  3. This shows a triangle having a yellow outline and a red fill. Observe red artefacts that go beyond the bounds of the triangle. If needed, adjust the zoom level.

Expected behavior
There should be no artefacts.

Screenshots

Real-world case:

egui_plot_issue_1

Screenshot from simplified PoC:
screenshot

Additional context

Latest egui and egui_plot

...
[dependencies.egui_plot]
version = "0.28.1"

[patch.crates-io]
egui_plot = { git = "https://github.com/emilk/egui_plot", branch = "main" }
...

x86 machine under Debian and X11 with NVIDIA driver 535.183.01, xfce4 with xfwm 4.18.0-1, no compositing

@berke berke added the bug Something isn't working label Jul 31, 2024
@CramBL
Copy link

CramBL commented Oct 17, 2024

I am also struggling with this issue.

I am downsampling line plots with many plot points to two plots that display the minimum values and maximum values respectively, think a signal envelope.

Then I try to fill the area between the minimum and maximum plots with polygons, to create a shaded area that signifies that it is a span, but I get these artifacts that @berke mentions too. Which makes it unusable.

@berke
Copy link
Author

berke commented Oct 18, 2024

@CramBL maybe this is related to the graphics stack. What platform are you on?

@CramBL
Copy link

CramBL commented Oct 18, 2024

@CramBL maybe this is related to the graphics stack. What platform are you on?

x86 Ubuntu 22.04

6.8.0-47-generic #47~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC x86_64 GNU/Linux

Driver: Intel Nouveau

configuration: depth=32 driver=nouveau latency=0 mode=2560x1440 visual=truecolor xres=2560 yres=1440

lshw -c video:

*-display
       description: 3D controller
       product: NVIDIA Corporation
       vendor: NVIDIA Corporation
       physical id: 0
       bus info: pci@0000:01:00.0
       logical name: /dev/fb0
       version: a1
       width: 64 bits
       clock: 33MHz
       capabilities: pm msi pciexpress cap_list rom fb
       configuration: depth=32 driver=nouveau latency=0 mode=2560x1440 visual=truecolor xres=2560 yres=1440
       resources: iomemory:600-5ff iomemory:620-61f irq:237 memory:bd000000-bdffffff memory:6000000000-61ffffffff memory:6200000000-6201ffffff ioport:3000(size=128)
  *-display
       description: VGA compatible controller
       product: Intel Corporation
       vendor: Intel Corporation
       physical id: 2
       bus info: pci@0000:00:02.0
       logical name: /dev/fb0
       version: 04
       width: 64 bits
       clock: 33MHz
       capabilities: pciexpress msi pm vga_controller bus_master cap_list rom fb
       configuration: depth=32 driver=i915 latency=0 resolution=2560,1440
       resources: iomemory:620-61f iomemory:400-3ff irq:238 memory:624c000000-624cffffff memory:4000000000-400fffffff ioport:4000(size=64) memory:c0000-dffff memory:4010000000-4016ffffff memory:4020000000-40ffffffff

This laptop: https://www.lenovo.com/us/en/p/laptops/thinkpad/thinkpadp/thinkpad-p16v-16-inch-intel-mobile-workstation/len101t0071

@CramBL
Copy link

CramBL commented Oct 18, 2024

Same issue (using your example repo) on x86 PopOS 22.04 with nvidia-driver-470, x11 and GNOME.

And on the same machine running Windows 11

@CramBL
Copy link

CramBL commented Nov 6, 2024

You can fairly easily reproduce this issue on https://www.egui.rs/ by selecting the Bézier Curve demo on the right:

Just move the circles to produce tight angles between the lines
e.g.
image

It also produces another surprising result occasionally, which is that the blue filled area spills over and goes outside the boundaries marked by the green lines.

@berke
Copy link
Author

berke commented Nov 25, 2024

@CramBL

You can fairly easily reproduce this issue on https://www.egui.rs/ by selecting the Bézier Curve demo on the right:

Confirmed. I've just tested with 0.29.1 the issue is still here.

  • The artefacts appear as a result of a call to ui.polygon(...) on a new Polygon
  • No artefacts appear if fill_color(Color32::TRANSPARENT) is called on the polygon

Running the test program under renderdoc one can see that the artefacts are present in the mesh received by OpenGL, so that it's not a driver issue.

Upon further inspection, I traced this down to the egui tessellator's "feathering" feature.
"Feathering" is apparently a cosmetic modification that creates a gradient on the outline of polygons. Unfortunately the egui implementation fails in some cases, causing these artefacts.

When I disable feathering as below I don't see the artefacts anymore.

	ctx.tessellation_options_mut(|to| {
	    to.feathering = false;
	});

EDIT: Unfortunately single-pixel lines drawn without feathering look really ugly.

@CramBL
Copy link

CramBL commented Nov 25, 2024

@CramBL

You can fairly easily reproduce this issue on https://www.egui.rs/ by selecting the Bézier Curve demo on the right:

Confirmed. I've just tested with 0.29.1 the issue is still here.

* The artefacts appear as a result of a call to `ui.polygon(...)` on a new `Polygon`

* No artefacts appear if `fill_color(Color32::TRANSPARENT)` is called on the polygon

Running the test program under renderdoc one can see that the artefacts are present in the mesh received by OpenGL, so that it's not a driver issue.

Upon further inspection, I traced this down to the egui tessellator's "feathering" feature. "Feathering" is apparently a cosmetic modification that creates a gradient on the outline of polygons. Unfortunately the egui implementation fails in some cases, causing these artefacts.

When I disable feathering as below I don't see the artefacts anymore.

	ctx.tessellation_options_mut(|to| {
	    to.feathering = false;
	});

EDIT: Unfortunately single-pixel lines drawn without feathering look really ugly.

Fantastic work! I know very little of graphics programming, but I could still try to take a look at the feathering implementation.

@CramBL
Copy link

CramBL commented Nov 25, 2024

Relevant issue: emilk/egui#1226

The issue was linked right above this line: https://github.com/emilk/egui/blob/83a30064f4812d0029532675a5f2bf38c257ad0e/crates/epaint/src/tessellator.rs#L460

Flipping CUT_OFF_SHARP_CORNERS to true resolves the issue in your egui_triangle_bug repo.

It seems @emilk and the rest are quite aware of the issue and the trade-off they have made in the current implementation. I assume it takes an expert + time to resolve this issue so I won't look into the implementation any further.

@berke
Copy link
Author

berke commented Dec 6, 2024

I had a look at the feathering code and I think one of the problems is a conceptual issue where every point in a path is associated with one normal. For a closed polygon, a point will be associated with two normals in general.
So a proper fix probably requires non-trivial changes to the tesselator.

In the meantime, an easy fix could be to expose an option somewhere to allow feathering to be disabled on a polygon-by-polygon basis.

@adamconkey
Copy link

Thanks for the discussion and pointers here @berke @CramBL, I had encountered a similar problem in a triangulation visualization and assumed I must had made a mistake in the polygons I was defining, but stumbled on this issue and realize I'm not the only one!

I am currently only seeing the problem I think in triangles that are really obtuse to the point that you have to zoom in to even see that it's a triangle and not just a straight line. I'd like to try to figure out a workaround though other than not drawing it, since they are valid and present triangles in the triangulation.

@adamconkey
Copy link

@berke many thanks! 🙏 I applied your suggestion to add

ctx.tessellation_options_mut(|to| {
    to.feathering = false;
});

and in my case it works great, the artefacts are no longer present.

Before:
Screen Shot 2025-01-01 at 11 24 44 AM

After:
Screen Shot 2025-01-01 at 11 25 12 AM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants