сглаженный рендеринг пикселей - PullRequest
3 голосов
/ 09 декабря 2011

Я пытаюсь реализовать сглаженный рендеринг пикселей. Моя основная идея - визуализировать 4 пикселя вместо 1 и назначить каждому «реальному» пикселю вес, основанный на его расстоянии от «виртуального» пикселя:

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));
}

Умножение весов x и y дает мне область перекрытия виртуального пикселя внутри каждого реального пикселя. Я наивно полагал, что это даст мне идеальный эффект сглаживания, но движущиеся пиксели внутри моей тестовой программы просто показывают ужасное мерцание. Это выглядит намного хуже, чем простые пиксели без сглаживания.

Однако, когда я переключаюсь с умножения на сложение, это выглядит намного лучше:

    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));

Добавление весов не имеет никакого геометрического значения. Так почему же это работает лучше? Что не так с первой версией? И есть ли еще лучший подход?

Ответы [ 2 ]

4 голосов
/ 09 декабря 2011

По запросу:)

Интуитивно понятно: ваши веса x и y выражают расстояние вдоль оси от виртуального до реального пикселя.Таким образом, фактическое расстояние составляет sqrt (w_x ^ 2 + w_y ^ 2).Объясняет, почему сумма работает лучше - она ​​гораздо ближе к этой форме, чем умножение.

3 голосов
/ 27 июня 2012

В моем коде в течение полугода скрывалась ошибка:

double weight_x1 = x - x0;
double weight_x0 = 1 - weight_x1;
double weight_y1 = y - y0;
double weight_y0 = 1 - weight_x1;   // BUG

Вы видите ошибку?Да, это классическая ошибка копирования и вставки:

double weight_y0 = 1 - weight_y1;   // FIXED

После исправления ошибки оригинальный подход к умножению выглядит очень хорошо.

...