render antialiased lines.

Started by
2 comments, last by haegarr 7 years, 11 months ago

Hello, currently i am learning graphics programming (with opengl) and sort of stuck on one thing. I wanted to draw anti-aliased lines but this task seems not a straight-forward one so searched extensively on internet how it can be done and found these 2 articles( and do not want to use MSAA. )

1. https://www.mapbox.com/blog/drawing-antialiased-lines/

2. http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter22.html

from the 1st one what i cannot understand is the antialiasing part, i mean how exactly it is interpolated between 2 normals?! if i just take its length it doesn't quite work. can anyone explain or have an idea why/how it should be about missing details?

regarding 2nd i read from some other articles(not particularly clear ones either) that there have been proposed better methods based on that article. if anyone have seen across such articles? Or in general if anyone has a fairly simple methods you can share. thanks answers will be much appreciated.

Advertisement

from the 1st one what i cannot understand is the antialiasing part, i mean how exactly it is interpolated between 2 normals?! if i just take its length it doesn't quite work. can anyone explain or have an idea why/how it should be about missing details?

The vertex normals are used to expand the geometry from an infinitesimal thin line to a line with thickness. The latter one is represented as a set of triangles that form a closed region. This is done in the vertex shader, because that is a place where vertices can be shifted around. The vertex shader is called on each vertex, and because that are a few points (usually with some additional informations) in space, they are far too spatially distributed to be used for anti-aliasing.

The fragment shader, on the other hand, is called for every pixel (called fragment in OpenGL) that is covered by the thick line's triangles. Anti-aliasing can be done here, because its spatial resolution is much finer than those of the vertices. To do anti-aliasing, you compute the distance of the pixel to the lines skeleton, i.e. to the original infinitesimal thin line. Letting corners aside, the distance from a point to a line is defined as the shortest distance from the point to every point on the line. If you think about it, it is the length of a vector that starts somewhere on the line, end at the point of interest, and is perpendicular to the line. Hence it can be called a normal, too, but its length depends on the pixel's position interested in. So let us name it difference vector just to avoid confusion.

Now, for anti-aliasing, you compare the length of the difference vector with half of the line with. Anti-aliasing should happen only if the pixel's is close enough to half of the line width, but is should not happen otherwise. So, as an example with numbers, use the line color if the distance is less than 90% of half of the line width, use color interpolation if the distance is between 90% and 110%, and discard the pixel if the distance is greater than 110%.

An interpolation factor can be calculated as

f := 1.0 - ( distance - 0.9 * half_width ) / ( ( 1.1 - 0.9 ) * half_width ) for 0.0 * half_width <= distance <= 1.1 * half_width

and hence will be 1.0 at 90% and 0.0 at 110% positions, and falls off straightly in-between. You can, of course, feed this value into a response curve if you want some other fall off profile.

Notice that color interpolation should be done using a linear color space, or the results will look oddly, but that is another topic ;)

EDIT: To be precise, an OpenGL fragment is meant to be a region on a surface that maps to a pixel.

thanks for the explanation, by color space you mean alpha values or all rgba?

thanks for the explanation, by color space you mean alpha values or all rgba?

Neither - nor. The alpha channel does not belong to the color space. Strictly seen, RGB is also not a color space but a color model. But yes, RGB is a term in daily speech that names what I mean. When interpolating color, you need do this in a linear color space. If you have sRGB, you first need to convert it into RGB (maybe your GPU does it for you on the fly).

This topic is closed to new replies.

Advertisement