Vector graphics
Image processing
Graphic design
Comments 14
+3

Отличная статья, и спасибо автору за то, что он коснулся проблемы гамма-коррекции в цветовых каналах sRGB и показал "как привыкли" и "как надо" смешивать цвета.

+2
А есть что-то на русском языке про «пиксельный неквадрат»? Или более подробно и для тупых написано? А то я там прочитал и ничего не понял.
0
Я вот весь этот материал знаю, и я бы ответил, но я не понял что такое «пиксельный неквадрат»
0
Это про момент из статьи, там есть ссылка на pdf-документ, автор которого рассказывает, что отдельный элемент цифрового изображения — пиксел — не является квадратом при рендеринге изображения с антиалиазингом. Точнее, что его нельзя воспринимать в таком ракурсе — как геометрический квадрат заполняемый треугольниками и трапециями для определения закрашенной области и выбора соответствующей яркости этого отдельного элемента изображения.
0
АА бывает разный, но в 2д обычно используется мультисэмплинг. Для каждого пикселя хранится несколько значений цвета (16), они там запакованы могут быть масочками, т.к. обычно там одинаковых много. Почему это круче по производительности чем просто в четыре раза увеличить размер канвы? потому что fragment shader только один раз проходится и видюха один и тот же цвет пишет в разные сэмплы из этих 16, это эффективно. Вот по памяти же проседает, это да. Операция которая «схлопывает» это копируя всё в обычную текстуру в opengl называется blitFramebuffer.

Флэш делал круче — там не FOR shape FOR pixel там наоборот, для пикселя знаем шейпы, можем каждый шейп на этих 16 сэмплах прогнать и тут же их «схлопнуть», незачем их хранить, поэтому по памяти он не проседает.

Ещё есть особенность как эти 16 точек распределены внутри пикселя — там немного повёрнутая сетка, чтобы избежать общих артефактов.
0
Ещё есть аналитический АА, вот там для шейпа сразу говорится сколько % пикселя он покрывает — и это автоматом вызывает ту проблемку с просвечиванием фона, поскольку два шейпа покрывающие вместе пиксель не складываются в alpha=1. Ну если фон прозрачный, то они могут сложится, если ADD использовать а не нормальный блендинг, но я не встречал кто это использует.

А теперь прикол — canvas2d скотина переключается между MSAA и AAA, и может сотворить чушь иногда. Вот нет гарантии что он попользует, даже если он полностью на GPU, например если это OffscreenCanvas в хроме.
0
Я не так давно всем этим занялся, начал с canvas2d и WebGL и пошёл вниз по годам :) Сейчас во флеше разбираюсь. Постепенно осознаю весь этот опыт поколений и как его сохранить и передать дальше.

До AGG ещё не добрался, для этого надо чтобы он мне был реально нужен.

Приколы с переключением видел прямо в исходниках хрома, поэтому получается что 2d контекст не так надёжен по результату. В данный момент делаю плагин для pixi для кэширования сглаженных шейпов в текстурах, самое близкое решение к этому есть у AwayJS, но моё будет круче.

Знаю ещё особенность что MSAA врубается даже на обычном SVG если ты под виндой с видеокартой nvidia pascal. Апофеоз — то что флэш делал в лохматом году, SVG на главной странице гугла фейлит если у тебя не паскаль. image
+1
Мда, действительно. Но AGG не обязательно использовать, там общее объяснение как работает сглаживание довольно внятно написано (высчитывает закрашенную площадь, правда детальных подробностей вроде не было).
0
Спасибо, обязательно разберусь! А то когда начну на конференциях выступать или на youtube стримы вести а мне неудобные вопросы придут :)
0

Это понятие идёт из темы цифровой обработки сигналов. "Квадрат" возникает, например, при передискретизации изображения из низкого разрешения в высокое методом ближайшего соседа. Один чёрный пиксель превращается в чёрный квадрат. При уменьшении картинки происходит обратный процесс — исходное изображение делится на квадраты, каждый из которых после вычисления среднего значения цвета превращается в один пиксель. "Квадрат" — это очень простой, но плохой фильтр, дающий заметный алиасинг. Для лучшего сглаживания мелких деталей перед уменьшением масштаба нужно пройтись по изображению фильтром нижних частот, т.е. удалить высокие частоты, чтобы избежать появления артефактов алиасинга.
Применительно к теме статьи — при рендеринге векторной графики, обладающей бесконечной чёткостью, в пиксельную, имеющую конечную чёткость, также имеет место передискретизация. Она может быть проведена без фильтра нижних частот (алгоритм Брезенхема), с простейшим фильтром — тот самый "квадрат" (алгоритм Ву), или с более сложным фильтром свёртки. На практике обычно на один пиксель редко приходится много мелких элементов векторной графики, и точности алгоритма Ву вполне хватает. Но если вы захотите, к примеру, отрендерить сетку из прямых чёрных линий, отстоящих друг от друга на 0.9 пикселя, то на каждые 9 квадратных пикселей придётся 10 линий, и вы получите артефакт алиасинга — 1 пиксель из 9 будет темнее остальных. В таком случае, чтобы получить равномерный фон, вам понадобится хороший фильтр нижних частот, а не "квадрат".

0
Это какой-то алгоритм после отрисовки через геометрическую площадь для выяснения яркости или фильтр после отрисовки? Есть ли название у этого алгоритма, чтобы его поискать с более подробным описанием?
0
Как уже подсказали выше, можно использовать мультисэмплинг, но он бывает разный. Вдобавок, алгоритмы с проходом по пикселям и по полигонам дают разные результаты на стыках двух фигур. Но сам по себе мультисэмплинг не решает проблему АА, а отодвигает её в более высокое разрешение. Вот отличная статья о растеризации с фильтрами высших порядков: Analytic Rasterization of Curves with Polynomial Filters, особенно показательны рисунки 5 и 6.
Only those users with full accounts are able to leave comments.  , please.