Краткое описание: Сглаживание линий толщины субпикселя - сложная работа, требующая ряда хитростей для вывода того, что мы интуитивно ожидаем увидеть.
Дополнительное усилие, которое вы видите, почти наверняка связано с сглаживанием. Когда толщина линии составляет менее одного пикселя, и линия не располагается прямо в центре ряда пикселей устройства, каждый пиксель, нарисованный для линии, будет пикселем частичной яркости. Чтобы убедиться, что эти частичные значения достаточно яркие, чтобы линия не исчезала, требуется больше работы.
Поскольку видеосигналы работают с горизонтальной разверткой (например, ЭЛТ, а не с ЖК-дисплеем), графические операции традиционно сосредоточены на обработке всего одной горизонтальной линии сканирования за раз.
Вот мое предположение:
Чтобы решить некоторые проблемы, растеризаторы иногда «подталкивают» линии, чтобы их виртуальные пиксели совпали с пикселями устройства. Если горизонтальная линия толщиной 0,25 пикселя находится точно на половине пути между линией сканирования устройства A и B, эта линия может полностью исчезнуть, поскольку она не регистрируется достаточно сильно, чтобы высвечивать какие-либо пиксели на линии сканирования A или B. Таким образом, растеризатор может подтолкнуть линия "вниз" чуть-чуть в виртуальных координатах, чтобы она выровнялась с пикселями устройства линии сканирования B и выглядела хорошо ярко освещенная горизонтальная линия.
То же самое можно сделать для вертикальных линий, но, вероятно, нет, если ваша видеокарта / драйвер гиперфокусирована на горизонтальных операциях сканирования (как и многие другие).
Таким образом, в этом сценарии горизонтальная линия будет отображаться очень быстро, потому что сглаживания вообще не требуется, и все это можно сделать за одну линию сканирования.
Вертикальная линия потребует анализа сглаживания для каждой горизонтальной линии сканирования, которая пересекает эту линию. Растеризатор может иметь специальный случай для вертикальных линий, чтобы рассматривать только левый и правый пиксели для вычисления значений сглаживания.
Диагональная линия не имеет ярлыков. У него повсюду зазубрины, так что повсюду много работы по сглаживанию. При подсчете сглаживания необходимо учитывать (подвыбирать) целую матрицу точек (не менее 4, вероятно, 8) вокруг целевой точки, чтобы решить, какую часть частичного значения дать пикселю устройства. Матрица может быть упрощена или исключена полностью для вертикальных или горизонтальных линий, но не для диагоналей.
Существует еще один пункт, который действительно касается только линий толщины субпикселя: как мы можем избежать полного исчезновения линии толщины субпикселя или появления заметных промежутков, когда линия не пересекает центр пикселя устройства? Вполне вероятно, что после того, как значения сглаживания рассчитаны на линии развертки, если нет четкого «сигнала» или достаточно освещенного пикселя устройства, вызванного виртуальной линией, растеризатор должен вернуться и «попробовать больше» или применить некоторую повышающую эвристику к получите более сильное отношение сигнал / пол, чтобы пиксели устройства, представляющие виртуальную линию, были осязаемыми и непрерывными.
Два соседних пикселя устройства на 40% яркости в порядке. Если единственный выход растеризатора для линии сканирования - это два смежных пикселя с 5%, глаз увидит зазор в линии. Не в порядке.
Если линия имеет толщину более 1,5 пикселей устройства, у вас всегда будет хотя бы один хорошо освещенный пиксель устройства на каждой линии сканирования, и вам не нужно возвращаться и стараться.
Почему 1,5 магическое число для толщины линии? Спроси Пифагора. Если пиксель вашего устройства равен 1 единице ширины и высоты, то длина диагонали квадратного пикселя устройства равна sqrt (1 ^ 2 + 1 ^ 2) = sqrt (2) = 1.41ish. Если толщина вашей линии превышает длину диагонали пикселя устройства, у вас всегда должен быть хотя бы один «хорошо освещенный» пиксель на выходе линии развертки независимо от угла линии.
Во всяком случае, это моя теория.