Reputation: 263320
I'm trying to implement anti-aliased pixel rendering. My basic idea is to render 4 pixels instead of 1, and give each "real" pixel a weight based on its distance to the "virtual" pixel:
void put_aa_pixel(double x, double y)
{
int x0 = int(x);
int x1 = x0 + 1;
int y0 = int(y);
int y1 = y0 + 1;
double weight_x1 = x - x0;
double weight_x0 = 1 - weight_x1;
double weight_y1 = y - y0;
double weight_y0 = 1 - weight_x1;
put_pixel(x0, y0, int((weight_x0 * weight_y0) * 255));
put_pixel(x1, y0, int((weight_x1 * weight_y0) * 255));
put_pixel(x0, y1, int((weight_x0 * weight_y1) * 255));
put_pixel(x1, y1, int((weight_x1 * weight_y1) * 255));
}
Multiplying the x and y weights gives me the overlapping area of the virtual pixel inside each real pixel. I naively assumed this would give me a perfect anti-aliasing effect, but the moving pixels inside my test program just display an aweful flicker. It looks much worse then simple pixels without any anti-aliasing.
However, when I switch from multiplication to addition, it looks much better:
put_pixel(x0, y0, int((weight_x0 + weight_y0) * 127.5));
put_pixel(x1, y0, int((weight_x1 + weight_y0) * 127.5));
put_pixel(x0, y1, int((weight_x0 + weight_y1) * 127.5));
put_pixel(x1, y1, int((weight_x1 + weight_y1) * 127.5));
Adding the weights doesn't seem to have any geometric significance. So why does this work better? What's wrong with the first version? And is there an even better approach?
Upvotes: 3
Views: 3821
Reputation: 263320
There was a bug lurking in my code for half a year:
double weight_x1 = x - x0;
double weight_x0 = 1 - weight_x1;
double weight_y1 = y - y0;
double weight_y0 = 1 - weight_x1; // BUG
Can you see the bug? Yes, it's a classic copy and paste error:
double weight_y0 = 1 - weight_y1; // FIXED
After fixing the bug, the original multiplication approach looks very nice.
Upvotes: 4
Reputation: 3918
As requested :)
Intuitively: your x and y weights express distance along axis from virtual to real pixel. So, the actual distance is sqrt(w_x^2 + w_y^2). Explains why sum works better - it's way closer to this form than multiplication.
Upvotes: 4