Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КГ - лекции Польского.doc
Скачиваний:
32
Добавлен:
06.11.2018
Размер:
1.3 Mб
Скачать

Лекция 15 Устранение лестничного эффекта (Antialiasing)

При растеризации различных примитивов (отрезков, окружностей, полигонов) неизбежно возникает одна проблема - рваные, ступенчатые края. Это явление, известное как лестничный эффект, совершенно естественное и, к тому же, неприятное следствие принятого подхода к подсветке пикселов, когда пиксел имеет только два состояния: включен/выключен. Алгоритмы рисования линий, рассмотренные ранее, реализует именно этот подход. При более высоком разрешении, когда соседние пикселы на экране находятся так близко друг к другу, что их трудно различить, лестничный эффект почти незаметен. Но при более низком разрешении лестничный эффект приводит к тому, что изображение выглядит грубым, компьютеризованным. Чем ниже разрешение, тем более явными становятся ступенчатые края, и тем менее реалистично выглядит изображение после растровой развертки. Для решения этой проблемы существуют специальные методы устранения лестничного эффекта. Для устранения лестничного эффекта используется тот факт, что пикселы можно высвечивать с различной интенсивностью и, если интенсивности соседних пикселов правильно подобраны, то они будут сливаться, формируя при этом гладкое изображение. Линии, нарисованные с помощью таких алгоритмов, выглядят слегка размытыми, но в этом и состоит устранение лестничного эффекта. Жертвуя четкостью, вы взамен получаете качество.

Существуют разные подходы к решению этой проблемы.

Первый метод – растеризовать все изображение (или отдельный примитив) с большим разрешением (например в 2 или в 4 раза), а затем усреднить значения цвета в пикселах. Например, при в 2 раза большем изображении, одному пикселу соответствуют 4 субпикселов, яркость при этом рассчитывается по формуле . В случае, когда одному пикселу соответствуют S сабпикселов, N=S2, кол-во градаций яркости пиксела равно S2+1.

Не обязательно растеризовать все изображение (т.к. при этом потребуется слишком много памяти), достаточно растеризовать часть полигона, соответствующую одному спану (ему будут соответствовать 4 субспана при 4-х кратном увеличении), а затем посчитать яркость пикселов этого спана.

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

Второй метод – рассчитывать яркость пикселов в зависимости от расстояния их центров до идеальной линии.

В отличие от предыдущих алгоритмов, выбирающих один пиксел, ближайший к линии, алгоритм растеризации с устранением лестничного эффекта высвечивает все пикселе, через которые проходит идеальная линия. Но ни один из них не светится с максимальной интенсивностью. Если идеальная линия проходит точно между пикселами, то каждый из них светится вполовину от нормальной интенсивности. Если линия ближе к какому-то из двух пикселов, то этот пиксел светится ярче, пропорционально расстоянию до другого. Пиксел высвечивается с максимальной яркостью только в том случае, когда линия проходит точно через его центр. Коэффициент яркости в DDA – алгоритме можно определять по расстоянию от линии до центра основного пиксела L= Y+0.5-floor(Y). Его яркость равна I1=1-fabs(L) (fabs(L)<=0.5). Если I1=1 – подсвечивается только основной пиксел, если меньше – то подсвечивается еще один – смещенный по Y в направлении знака L, I2=1-I1.

Третий метод – рассчитывать яркость пикселов в зависимости от площади части пиксела, которую покрывает примитив. Для полигонов все просто, а для линии используют прямоугольник шириной в 1 пиксел.

Сначала разобьем полигон горизонтальными линиями на уровне каждой из вершин. Таким образом, мы получим набор трапеций (или треугольников) с горизонтальными основаниями. Затем, каждую из этих трапеций, в свою очередь, снова разобьем по каждой горизонтали с целой координатой (границе пикселов). Теперь мы получили набор трапеций с горизонтальными основаниями, высотой меньшей или равной 1 пикселу и целиком лежащих в пределах одного спана.

Каждая из них разделяется на части вертикальными линиями, проходящими через вершины этой трапеции и границы пикселов. В результате, каждому пикселу будет соответствовать несколько трапеций с вертикальными основаниями. Рассчитывается их площадь , и по сумме площадей трапеций, попавших в пиксел определяется его яркость. Алгоритм не требует больших объемов памяти, т.к. горизонтальные трапеции обрабатываются последовательно. Единственное, одному спану может соответствовать несколько горизонтальных трапеций, в этом случае придется завести одномерный массив, в котором будет накапливаться площадь пикселов.