A big customer was furious that they had bought a part that didn't perform the way they wanted, so I was voluntold to fix it.
I was given a ridiculous timeframe to come up with a solution and present them to our customer in a big in-person meeting with all the decision makers. I managed to implement three different alternatives so that the customer would feel they had some agency selecting the one they liked the most. The best looking by far was a form of AAA.
This was one out of several of these big last minute fires I was assigned to solve. Years later my manager told me how great it was knowing that the could throw any crap at me and I would be able to fix it in time.
However, these sort of experiences are why I struggled with burnout during my career, which led me to save like crazy to retire as early as possible, which I did.
For younglings out there: when they ask you to do the impossible, remember that failure IS an option. Push back if you think they are asking you for something unreasonable.
Also, going to add "voluntold" to my lexicon :D
1. antialiasing should be done in linear rgb space instead of srgb space [1] [2]
2. because of the lack of (1) for decades, fonts have been tweaked to compensate, so sometimes srgb is better [3] [4]
Do you have advice on linear vs srgb space antialiasing?
[1] https://www.puredevsoftware.com/blog/2019/01/22/sub-pixel-ga...
[2] http://hikogui.org/2022/10/24/the-trouble-with-anti-aliasing...
[3] https://news.ycombinator.com/item?id=12023985
[4] http://hikogui.org/2022/10/24/the-trouble-with-anti-aliasing...
Unfortunately, this is completely context dependent. One central point is, whether or not the graphics pipeline is instructed to perform corrections (GL_FRAMEBUFFER_SRGB in OpenGL), as that changes the answer. Another point is, in which context blending is performed. Luckily the developer has full freedom here and can even specify separate blending for alpha and color [1], something that GPU accelerated terminal emulator Alacritty makes use of [2], though it doesn't do MSDF rendering.
One thing I can say though: The alpha, the fading of edge, has to be linear at the end or perceived as such. Or rather if the edge were to be stretched to 10 pixels, each pixel has to be a 0.1 alpha step. (If smoothstep is used, the alpha has to follow that curve at the end) Otherwise the Anti-Aliasing will be strongly diminished. This is something you can always verify at the end. Correct blending of colors is of course a headache and context specific.
> fonts have been tweaked to compensate, so sometimes srgb is better
This should not concern MSDF rendering. These tweaks happened at specific resolutions with monitors popular at that time. Especially when considering HiDPI modes of modern window systems, all bets are off, DPI scaling completely overthrows any of that. MSDF is size independent and the "tweaks" are mainly thickness adjustments, which MSDF has control over. So if the font doesn't match as it looks in another rendering type, MSDF can correct for it.
[1] https://developer.mozilla.org/en-US/docs/Web/API/WebGLRender...
[2] https://github.com/search?q=repo%3Aalacritty%2Falacritty+ble...
What WebGL2 is still missing is MSAA texture objects (it only supports MSAA render buffers), which makes it impossible to directly load individual samples in a shader (useful for custom-resolve render passes). That's only possible in WebGPU.
I have done a few live visualization based blog posts, and they take me ages to do. I kind of think that's the right idea though. There is so much content out there, taking longer to produce less content at a higher quality benefits everyone.
[1] https://github.com/FrostKiwi/treasurechest/commits/main/post...
For font and 2D vector rendering it's likely, in fact afaik, some solutions, such as Slug already do.
But for 3d rendering I don't know of any solutions.
For an intuition, consider two triangles that intersect the same pixel.
Consider if say one has 20% coverage and the other 30%, does that pixel have 50% coverage, 30% by one, 20% by one and 10% by another, or any other conceivable mix? It's very difficult to say without selecting specific points and sampling directly.
How to blend multiple shapes on the same quad, within a draw call is shown in the section "Drawing multiple?". There you fully control the intersection with the blending math.
Finally, there is always the gamma question, which is true for all AA solutions. This is not covered in the post, but that might mess with the results, as is true for any kind of blending.
[1] https://developer.mozilla.org/en-US/docs/Web/API/WebGLRender...
Still, non-standard rendering approaches are very much a thing [1] and I could see setups like [2] be used in scientific particle visualizations.
[1] https://www.youtube.com/watch?v=9U0XVdvQwAI
[2] https://bgolus.medium.com/rendering-a-sphere-on-a-quad-13c92...
Found it by going to the comments since the comments are GitHub issues the "x comment" is a link to the issues page.
On what GPUs and through what APIs did you see this? This seems fairly weird. I especially wouldn't expect Apple to have problems.
It's just so happens to produce visible artifacts in this case. I suppose for 3D scenes it's mostly fine.
This article will probably help for future reference though!
On a meta level - I feel like I've seen anti-acronym sentiment a lot recently. I feel like it's never been easier to look these things up. There's definitely levels of acronyms which are anti-learning or a kind of protectionism, but to my mind there are appropriate levels of it to use because you have to label concepts at a useful level to accomplish things, and graphics settings of a game definitely are on the reasonable side.
And even if you know every detail, that's still the best course of action, I think. Which kind of antialiasing you prefer, and how it trades with performance and resolution is highly subjective, and it can be "none".
There are 3 components to rescaling/rendering pixels: aliasing, sharpness and locality. Aliasing is, well, aliasing, sharpness is the opposite of blurriness, and locality is about these "ringing" artefacts you often see in highly compressed images and videos. You can't be perfect on all three. Disabling antialiasing gives you the sharpest image with no ringing artefacts, but you get these ugly staircase effects. Typical antialiasing trades this for blurriness, in fact, FXAA is literally a (selective) blur, that's why some people don't like it. More advanced algorithms can give you both antialiasing and sharpness, but you will get these ringing artefacts. The best of course is to increase resolution until none of these effects become noticeable, but you need the hardware.
The best algorithms attempt to find a good looking balance between all these factors and performance, but "good looking" is subjective, that's why your best bet is to try for yourself. Or just keep the defaults, as it is likely to be set to what the majority of the people prefer.
I wouldn’t be surprised if there’s now a market demand for that to spread back to PC land.
PlayStation does have shining examples of user-friendly settings UI though, namely in their PC ports. Look at this UI in Ratchet and Clank:
https://x.com/digitalfoundry/status/1684221473819447298
Extensive tooltips for each option and any time you change a setting it is applied immediately to the paused game while you're still in the settings menu allowing you to immediately compare the effects.
It’s nowhere near as simple as 3 settings now there are different antialiasing techniques, path tracing lighting or reflections, upscaling (multiple algorithms) etc.
Nothing is all just fully positive and each has tradeoffs
I've been using MSAAx4 in my rendering engine for some time and only recently have considered switching to a FXAA / TAA implementation. I'm actually not sure I'm going to go through with that now. I definitely learned a lot here, and will probably use the analytical approach for UI items, I hadn't heard about that anywhere.
Not often you see graphics-programming stuff on HN. For anyone interested in more graphics write-ups, this list of frame breakdowns is one of my favorite resources:
One of my favorites: https://acko.net/blog/how-to-fold-a-julia-fractal/. This helped me understand the relationship between trigonometric functions and complex numbers like nothing else I've ever seen.
And now today there’s this post and your comment here in the front page.
Which is another way of saying: a proof of God would be going through life without a constant stream of surprisingly meaningful coincidences.
Unbiased reality is inherently a blind but inventive "Creator".
SDF(or mSDF) isn't the future. It's already "good enough" classic.
> This works, but performance tanks hard, as we solve every > bezier curve segment per pixel
This is "the future" or even present as used in Slug and DirectWrite with great performance
https://sluglibrary.com/ https://learn.microsoft.com/en-us/windows/win32/directwrite/...
[0]: https://www.microsoft.com/en-us/research/wp-content/uploads/... [1]: https://patents.google.com/patent/US20070097123A1/en
Had to do a _lot_ of work to make it production-ready, as their voronoi-based tesselation goes pathological on a lot of Asian glyphs.
Though a little caveat from my side, as I have written both 2D and 3D rendering engines. Let me tell you, they could not be more different. It is not just another dimension but completely different goals, use-cases and expectations.
So instead of:
> Everything we talked about extends to the 3D case as well.
I would say the entire post is mostly about 3D, not 2D rendering. If you are curious about this topic being approached for 2D rendering here is a nice write-up I found about that: https://ciechanow.ski/alpha-compositing/
One particular criteria for AA techniques that no one cares about in 3D but is very relevant in 2D is correctness and bias. AAA for example is heavily biased and thus incorrect. Drawing the exact same shape multiple times in the same place will make it more opaque / darker. The same thing does not happen with MSAA which has a bounded error and is unbiased.
(Thick) line drawing is especially interesting to me, since it's hard [1].
I also stumbled upon this [2] recently and then wondered if i could use that technique for every shape, by converting it to quadratic bezier curve segments.
Do you think that's a path to follow?
[0] https://github.com/Lichtso/contrast_renderer
[1] https://mattdesl.svbtle.com/drawing-lines-is-hard
[2] https://scribe.rip/@evanwallace/easy-scalable-text-rendering...
- Implicit Curve Rendering (Loop-Blinn) and stencil geometry (tessellation-less) for filling
- Polygonization (with tangent space parameter distribution) of offset curves for stroking
> by converting it to quadratic bezier curve segments
Mathematically, the offset curve of a bezier curve is not a bezier curve of the same degree in the general case (exceptions are trivial cases like straight lines, circles and ellipses). Instead you get terrible high degree polynomials. You will have to approximate the offset curve anyway. I choose to use polygons (straight line segments), but you could also use splines (bezier segments), it is just overtly complex for little to no benefit IMO.
BTW, distance fields and offset curves are very similar. In fact the distance field is the set of all possible offsets of offset curves and the offset curves are the isolines on the distance field.
Here is a good summary of all the edge cases to think about in 2D rendering: https://www.slideshare.net/slideshow/22pathrender/12494534
About subpixel AA: Don't bother, LCDs are on the down trend.
OLEDs have subpixels, too. The real problem is the growing diversity in subpixel arrangements, making it impractical to have a good subpixel AA method for every display type on the market. And mobile platforms have it worse, because screen rotation means you need to be able to change AA methods on the fly.
The solution presented relies on signed distance fields, yet skims over the important part - a distance to what? In 2D it is obvious, we are measuring distance to an edge between the object and its background, to a silhouette.
In 3D, when objects may rotate producing self-occlusions, things get more complicated - what are we measuring the SDF against? The silhouette of a 3D object's 2D projection is ever-changing and cannot be trivially precomputed.
Sure it's better than TAA, but come on, this can't be the ultimate end for gaming graphics... At least I hope it isn't.
To do alpha blending correctly you need to blend with what's behind the object. But what if you haven't rendered what's behind the object? You won't have anything to blend with!
This means you first have to sort all the objects you're rendering and render them in-order. It also means you can't use a depth pre-pass because you need to draw what's behind the object even for the parts you already know will be covered by the object in front of it. There's a bunch of more reasons to avoid it, but those are some of the basic ones.
An alternative is to draw only a few pixels of what's behind the object you're rendering at the edges of the object that's in front and then alpha blend those extra samples together, which seems to be the solution proposed in the article for actual 3D games. So then the catch is that you're doing MSAA, just with high-quality blending rather than the standard averaging of the samples.
Hmm... On my Android phone I definitely see a difference between 2x and 4x, but it's not "rounded" like the iPhone one.