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

Align shapes to physical pixel grid #5164

Open
emilk opened this issue Sep 25, 2024 · 1 comment
Open

Align shapes to physical pixel grid #5164

emilk opened this issue Sep 25, 2024 · 1 comment
Labels
epaint visuals Renderings / graphics releated

Comments

@emilk
Copy link
Owner

emilk commented Sep 25, 2024

When painting shapes, it is sometimes preferably to align them to the physical pixel grid.

There are a few different ways we can attack this:
A) A document and make it easy for users to align
B) Always align shapes, and opt-in to non-aligned shapes
C) Always align all shapes

I think B is preferable, the question is how to accomplish it on a per-shape basis.

We could add a bool flag to each shape, and have the tessellator do the alignment, unless the flag is set.
Or the Painter aligns all shapes, unless you call painter.add_unaligned(…) or something like that.

When to align

Sharpness

We always align text to the physical grid (unless rotated), because otherwise it looks blurry.

Similarly we align many vertical lines, horizontal lines, and rectangle frames to make them sharper:

Tiling

When painting many rectangles that should seamlessly tile:
#4928 (comment)
image

In this case, the end results would look better if the rectangle was aligned to the physical pixel grid.

When not to align

When you want to smoothly animate something.

@emilk
Copy link
Owner Author

emilk commented Dec 25, 2024

Additional thoughts

Feathering and rounding is separate issues

Feathering (a form of AA) is for soothing out the edges of shapes.
The rounding of coordinates to physical pixels is a separate issue.
We may want want to give full control of both.

For instance: a line that is 1.3 physical pixels wide should maybe be rounded to be centered on a physical pixel, but still use feathering so that it appears wider than a line that is 0.7 physical pixels wide.

However, for a thick and filled box, rounding all the corners to be on the corners of physical pixels results in the same effect as turning off anti-aliasing.

Always round thin vertical and horizontal lines to the physical grid

Anti-aliasing is always useful for diagonal lines. For vertical and horizontal lines (like the borders of a rectangle) it is usually unnecessary, except for the case when these lines are thick AND animated (either moving or growing/shrinking).

Consider a thick box moving sideways. Without AA, a new column of pixels gets turned on at regular intervals, which is an annoying discontinuity. If we turn on AA, each new column "fades in", removing the jarring "popping". So AA should be ON in the this case. BUT in the case of a thin line moving to the right, then AA will turn a solid column of pixels into two columns of gray pixels, and then into a another column of solid pixels again, and so on. This will cause the line to appear to "blink" or "pulsate" as it moves, which is very annoying. If we round to physical pixels, then we will always have a solid column of pixels turned on, so at each point in time the line will have the same brightness and width. Yes, it will still jump in discreet steps, but in my experience, this is much more desirable. I'll try to generate a video to motivate this further.

In any case, this leaves us with the conclusion that thin vertical and horizontal lines should always be rounded to physical pixels, and nothing else.

What is the cutoff for "thin"? My instinct says it should be somewhere around two physical pixels, but this may require experimentation (and should be a setting of TessellationOptions).

Limitations

Prefect tiling of thick rectangles still require turning off AA (or rounding the corners to physical pixels, which amounts to the same thing).

Where to do the rounding?

We could do the rounding in egui::Painter. That way you can turn it on/off for specific parts of your application.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
epaint visuals Renderings / graphics releated
Projects
Status: No status
Development

No branches or pull requests

1 participant