All the anti-aliased line drawing algorithms I've come across simply say that the "intensity" of the pixels needs to be a function of how much of the line passes through it. This works fine on constant backgrounds (ie white), but I want to be able to draw on a background of arbitrary complexity, which means replacing intensity with transparency and alpha blending the line with the background.
Doing this necessarily changes the color of the line depending on what the background is, since for a 1px line it rarely passes exactly through a single pixel, giving it full opacity. I'm curious if there's a technique for drawing these blended lines while maintaining the appearance of the original color.
Here's an example of my rendering attempt on a colorful background. You'll note the vertical/horizontal lines are drawn as a special case with the real color, and the anti-aliased diagonal lines have a blue tint to them.
Is there a proper way to blend anti-aliased lines into the background while maintaining the appearance of the proper line color?
Edit: and code for actually plotting points:
// Plot pixel at (x,y) with color at transparency alpha [0,1]
static inline void plot(pixel_t *pixels, uint16_t stride, const pixel_t &color, uint16_t x, uint16_t y, uint8_t alpha) {
pixel_t pix = pixels[y*stride+x];
pixels[y*stride+x].r = (uint16_t)color.r * alpha/255 + pix.r * (255 - alpha) / 255;
pixels[y*stride+x].g = (uint16_t)color.g * alpha/255 + pix.g * (255 - alpha) / 255;
pixels[y*stride+x].b = (uint16_t)color.b * alpha/255 + pix.g * (255 - alpha) / 255;
}
Edit: For future generations, blending green and blue can give your lines a blue-ish tint.