4
votes

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.

enter image description here

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.

1
I don't think you're doing the alpha composition correctly. I tried drawing that green color over your background with various alpha values in an image editing program and I couldn't reproduce that blue color.Pubby
@Pubby: I'm using a fixed-point version of Wu's algorithm (per Abrash's Black Book), and I just added the snippet that actually blends my pixels with the background. Also I should add the color line I was trying to draw was (0,128,0) RGB.gct
Your GPU comes with AA algorithms built in- possibly several. Why not just use them?Puppy
@DeadMG: Because I want to write it myselfgct
Just spotted my mistake: Blending green with blue at the end. FMLgct

1 Answers

2
votes

I'm glad you spotted the bug in your code.

Another problem to watch out for is gamma correction. Anti-aliasing must be applied in a linear color space to look correct, but most of the time to save some processing steps it is applied in a gamma-corrected color space instead. The effects are much more subtle than your example.