Что такое отрисовка в векторе
Что такое векторное изображение и зачем вам логотип в векторе
Всё это действительно так (почти всегда). Но обо всём по порядку: сегодня я вам подробно расскажу о том, что такое векторный формат и почему логотипы желательно делать в нем. В конце статьи поделюсь информацией о том, как сделать логотип в векторном формате.
Содержание статьи:
Что такое векторная графика
#Векторная графика — это категория компьютерной графики, которая для представления изображения использует фигуры, построенные по математическим формулам.
Обещаю, скоро всё станет понятнее, нужно чуть-чуть потерпеть…
Помните, в школе на геометрии нужно было построить окружность в системе координат? Для этого достаточно было знать только координату центра окружности и её радиус, верно? Таким же образом рисуется окружность и в векторной графике.
Подобным же образом рисуются кривые, прямые, ломаные линии, многоугольники, эллипсы и прочие, так называемые графические примитивы.
Помимо координат и размеров этим элементам в программе для создания векторных изображений можно задать:
Но основными параметрами в векторной графики являются координаты опорных точек и направление (векторов) линий, проходящих через них. Отсюда и название.
Например рисунок ниже — это один единственный примитив, представленный замкнутой кривой линией:
А этот примитив ниже и вовсе поражает своей фотореалистичностью:
Вся «фотография» справа также является одной кривой, но окрашена она сетчатым градиентом (слева показана эта самая сетка) — плавных переходов цвета в ней так много, что мы отчётливо видим все светотени и даже текстуру кожи.
Я обещал, что станет проще, но, похоже, всё становится только сложнее… Сейчас исправлюсь!
Чем векторная графика отличается от растровой?
Векторная графика часто противопоставляется растровой. И правильно делает: они отличаются на фундаментальном уровне со всеми вытекающими.
Любое #растровое изображение состоит из матрицы (сетки) пикселей. Каждому из этих пикселей приписано его местоположение и цвет. И растровое изображение содержит в себе эту информацию о каждом своём пикселе. Этим объясняется зависимость «веса» растрового изображения от его размера — чем больше в нём пикселей, тем больше информации ему нужно в себе хранить.
Посмотрите примеры ниже:
Слева — векторный синий круг размером 200 на 200 пикселей. Да, хотя в векторной графике самих пикселей нет, размер изображения можно задать и в них.
Справа — растровый синий круг такого же размера.
При этом файл векторного круга весит 2,16 Кб, а растрового — 4,73. Разница небольшая, да. Если бы они оба были размером по 100 на 100 пикселей, разница была бы ещё меньше: 2,16 Кб против 2,24. Но чем больше будет размер обоих картинок, тем значительнее будет разница в весе файла.
К примеру: вес векторного круга размером 1000 на 1000 пикселей будет всё так же 2,16 Кб, а вес растрового файла будет уже 27,6 Кб — в 12,5 раз больше! Если брать рисунки 10000 на 10000 пикселей, то веса файлов будут 2,16 против 640 Кб — растровый файл будет уже в 300 раз тяжелее векторного.
Почему это происходит? В то время, как растровому файлу в последнем случае приходится нести информацию о 100 миллионах точек (пикселей), векторному всё также нужно знать лишь 3 параметра — размер круга, его местоположение и цвет.
Что будет, если увеличить те двухсотпиксельные круги?
Увеличенный фрагмент векторного файла:
Увеличенный фрагмент растрового файла:
Пиксели. Они повсюду. Вы их точно увидите!
Однако, не стоит полагать, что растровая графика во всём уступает векторной. У обеих категорий есть как плюсы, так и минусы, и каждой своё применение.
Плюсы векторных изображений:
Минусы векторных изображений:
Распространённые векторные форматы это: SVG, PDF, EPS, AI и CDR. Последние два разработаны специально для программ Adobe Illustrator и CorelDRAW соответственно, и максимально верно поддерживаются именно ими. Оба эти формата могут читаться и редактироваться другим ПО, но с некоторыми ограничениями.
Наиболее распространённым форматом является SVG, его можно просматривать и редактировать в любом векторном редакторе, и он поддерживается всеми современными браузерами.
Характеристики растровых файлов — полная противоположность оных у векторных.
Плюсы растра:
Минусы растра:
В двух словах (очень общо и без тучи возможных нюансов) можно сказать, что для фотографий и фотоподобных изображений лучше использовать растровую графику, для всего остального — векторную. Последнюю всегда можно легко переконвертировать в растровый формат любого размера.
К слову, популярные форматы растровых изображений — это хорошо знакомые всем PNG, JPG, GIF, а также TIFF, PSD, BMP.
А теперь я расскажу вам один секрет.
На самом деле, мы не можем увидеть действительно векторное изображение на современных дисплеях.
Даже если открыть векторный редактор и нарисовать в нём векторный синий круг, изображение, которое мы увидим будет растровым! Всё дело в том, что все современные дисплеи состоят из пикселей, и если открыть файл с векторным изображением, компьютер (плеер, телефон или другое устройство) преобразует его в растровое. Иначе просто не получится.
Но как говорил мой французский тёзка: «Зорко одно лишь сердце. Самого главного глазами не увидишь.»
Почему логотип должен быть векторным
Несмотря на то, что, как я сказал, на современных дисплеях любое изображение будет представлено в растровом виде, логотипы и многую другую графику изначально стоит создавать в векторе.
Причины, по которым это необходимо, основываются на всех преимуществах векторных форматов.
Во-первых, это, конечно, вес файлов. Векторные файлы уступают растровым в этом параметре только при очень малых физических размерах или сложных фотореалистичных изображениях. Но в малых размерах и разница между весами будет минимальной, пусть даже и в пользу растровой графики. А фотоподобные логотипы встречаются крайне редко (лишь в исключительных случаях), и всё равно, начиная с определённого размера, вектор-таки начнёт выигрывать.
Разумеется, это не самое главное преимущество, но порой, например, в дизайне сайта (где необходима быстрая загрузка картинок) это может быть существенным.
Типичный пример, когда для качественной печати изображения не хватило разрешения (векторный рисунок решил бы эту проблему). Думаю, вам частенько встречается подобное..
Но дело даже не в том, что вы можете сделать из векторного изображение очень большое растровое, а в том, что вы можете сделать изображения абсолютно любого размера! Скажем, для шапки сайта логотип нужен ровно 60px в высоту, для фирменного бланка — 300 px в ширину, а для печати фирменных футболок — не менее 4000 px. И все эти размеры можно легко подготовить, используя всего один векторный файл.
В-третьих, относительно простое и более качественное редактирование. Это не значит, что векторный формат поощряет постоянные изменения логотипа. Но однажды вам может понадобиться анимированная или 3D-версия, какой-то особый праздничный вариант, или вы решите добавить в логотип слоган — и в этом случае работать с векторным файлом будет намного удобнее, а итоговый вариант будет качественнее.
В-четвёртых, это — широкие возможности использования. Из векторного лого легко сделать растровый, а вот перевести логотип в векторный формат из растра не так-то просто (но об этом ниже). По мимо этого, во многих областях применения подойдут только векторы. Хотите выжечь лого в дереве? Нужен вектор. Сделать гравировку? Вектор. Изготовить печать (штамп)? Вектор. Вышить, вырезать, оттиснить, залакировать, изготовить вывеску… Для всего этого понадобятся именно векторные файлы, а не тот JPG, который стоит у вас на сайте или на аватарке в соцсетях.
Как сделать логотип векторным
К сожалению, всё ещё очень много компаний имеет на руках только растровый логотип, да и то небольшого размера — годящийся разве что для шапки сайта.
Что делать, если ваша организация оказалась в их числе, а логотип уже давно «вырос» и хочет побывать кроме сайта где-то ещё?
Вариантов у вас немного и оба они прозаичны. Можете сделать векторный логотип сами или обратиться к специалисту.
Подозреваю, что, если вы до сих пор читаете эту статью, то с векторной графикой и соответствующими редакторами вы совсем не знакомы.
От себя могу вам порекомендовать программу для векторной графики InkScape. Редактор бесплатный, относительно простой в использовании (для векторного редактора) и своим функционалом почти ничем не уступает именитым Illustrator и CorelDRAW (по крайней мере в отрисовке логотипов).
Итак, как перевести логотип в вектор:
Ниже представлены примеры векторизаций одного логотипа:
А. Автоматическая (программная) векторизация растрового логотипа шириной 200 px;
Б. Автоматическая векторизация растрового логотипа шириной 500 px;
В. Автоматическая векторизация растрового логотипа шириной 1000 px;
Г. Ручная отрисовка логотипа в векторный формат.
Как видно, качество векторизации растёт с увеличением исходного файла, но всё равно оно всегда будет уступать отрисовке. Если присмотреться в вариант «В», можно увидеть, что действительно прямых углов нет ни в окне, ни в кирпичах, ни в буквах.
При заказе отрисовки логотипа в векторе у дизайнера или в студии, следует уточнить, что именно они подразумевают под этой работой: автоматическую векторизацию (также называемую трассировкой) или ручную отрисовку (по сути создание векторного логотипа по имеющемуся у вас изображению). Последнее будет дороже, но и качество выйдет намного выше. Также обязательно попросите показать примеры подобных работ — по ним можно будет оценить и навыки исполнителя и метод, который он использует.
Некоторые дизайнеры используют вначале трассировку, а затем дорабатывают логотип вручную. Но даже после этого могут остаться недочеты. Лично я предпочитаю вообще не пользоваться программной векторизацией. Мне проще сразу создать логотип в векторе вручную, чем исправлять многочисленные ошибки машинной обработки.
И последний небольшой совет:
То, что у вас нет на руках векторных файлов логотипа, — это тревожный звоночек, означающий, что скорее всего и сам логотип у вас не очень…
Поэтому, если вы всё же решились на векторизацию логотипа и тем более обратились за помощью к профессионалам, уточните, не будет ли лучше разработать совсем новый дизайн. В любом случае необходимых файлов вы получите не меньше.
Если остались какие-то вопросы по векторной графике, отпишитесь в комментариях!
Отрисовка векторной графики — триангуляция, растеризация, сглаживание и новые варианты развития событий
В далёком 2013м году вышла игра Tiny Thief, которая наделала много шуму в среде мобильной Flash (AIR) разработки из-за отказа от растровой графики в билдах, включая атласы анимации и прочего — всё что было в сборке хранилось в векторном формате прямиком из Flash редактора.
Это позволило использовать огромное количество уникального контента и сохранить размер установочного файла до
70 мегабайт (*.apk-файл из Google Play). Совсем недавно снова возник интерес к теме отрисовки векторной графики на мобильных устройствах (и вообще к теме отрисовки вектора с аппаратной поддержкой), и меня удивило отсутствие информации «начального» уровня по этой теме. Это обзорно-справочная статья по возможным способам отрисовки вектора и уже существующим решениям, а так же о том, как подобные вещи можно сделать самостоятельно.
Основной способ
К отрисовке вектора чаще всего подходят так — берут все фигуры, кривые и прочие вещи, проходятся по ним алгоритмом триангуляции (разделение замкнутых контуров на треугольники), считая разного рода обводки и линии такими же закрашенными объектами, и получают какое-то приближённое представление описанной математической формулой фигуры.
То есть векторный круг, отрисованный таким образом, будет на самом деле многоугольником. Критерием качества в данном случае будет являться количество и размер треугольников, полученных в итоге:
Причина таких обходных путей простая — графическая карта умеет эффективно работать только с вершинами, треугольниками и пикселями (про GPGPU немного другая история, но в данном контексте стоит только упоминания вскользь). Если же рисовать математически верные представления моделей с помощью CPU, то это будет занимать намного больше времени. Поэтому просто триангулируем и отправляем графической карте на отрисовку в сыром виде, как есть.
Подводные камни
Подобная сырая отрисовка треугольников приводит к появлению эффекта алиасинга — ступенчатости краёв изображения (это хорошо заметно на скриншоте выше). Эта проблема присуща любой непрозрачной геометрии, представленной в виде треугольников.
Если же посмотреть на скриншот Tiny Thief, то сразу видно, что игра лишена этого недостатка — края объектов красиво сглажены.
Field study
Все описанные ниже вещи я проверял с помощью Adreno Profiler, NVIDIA PerfHUD ES и Unity (проверка работоспособности предложенных вариантов решения).
Вот что покажет Adreno Profiler если включить режим цветной сетки:
То есть отрисовка тем самым методом триангуляции. Вершины при этом красятся напрямую, без текстур (параметр color у вершин).
Вот что находится в альфа буфере (очевидно у Adreno GPU есть такое понятие как «альфа-буфер»):
По краям объектов тонкая однопиксельная полоска. Интересно, что на гранях между соседними объектами (белый фон-цветная буква) альфа канал «белый», то есть весь логотип рисуется одним проходом, а сглаживание внутри подобных объектов реализовано немного другим способом.
Суть сглаживания более или менее ясна — при триангуляции добавляем тонкий набор треугольников вдоль края объекта.
Сколько бы я ни пробовал приближать картинку — не смог разглядеть эти хитрые тонкие треугольники. Но, к счастью, Adreno Profiler, в отличие от PerfHUD, позволяет экспортировать геометрию в текстовом виде.
Сборка по кускам
Написав простой парсер, получилось восстановить исходный меш в Unity. Но меня ждала странная картина:
Рамочки без сглаживания. В режиме просмотра сетки тоже не видно заполняющих треугольников:
Долго не мог понять в чём дело. Оказалось, что заполняющие треугольники вывернуты в другую сторону. Это становится видно, если посмотреть на логотип с другой стороны:
Также заметно, что между элементами логотипа присутствуют пустые линии, которые заполнены градиентами (градиент сделан с помощью закрашивания вершин в соответствующие цвета), и при этом нет сглаживания.
Если убрать backface culling в шейдере, то получим то, что хотели получить в итоге:
Но возникает интересная особенность — если приближать этот объект к камере, то сглаживание становится слишком заметным и выглядит как размытие:
То есть триангуляция происходит каждый раз по месту, в зависимости от размеров экрана, и не предполагает изменения размеров этого объекта. Размер треугольников рассчитывается таким образом, чтобы общая ширина составляла один экранный пиксель или меньше.
Практически все объекты на экране отрисовываются таким же образом. Исключение составляет задний фон, который рендерится один раз в текстуру.
Статистика
Достаточно интересно посмотреть сводную информацию об отрисовке персонажей, в среднем каждый герой (стражник, повар) в триангулированном виде составляет около 3-4 тысяч треугольников. Это примерно как хорошего качества лоу-поли 3Д модель. Сетка настолько плотная, что кажется что объект отрисован текстурой:
Логотип занимает почти 9 тысяч треугольников. Общее количество draw calls в среднем около сотни (было бы намного больше, если бы задний фон не рисовался в виде текстуры), но ФПС стабильно максимальный даже на стареньком ZTE V811 (Билайн смарт 2).
В общем пока берём в копилку первый (и основной) способ отрисовки векторной графики:
триангулируем нашу векторную картинку, делаем вдоль стыков тонкую границу с промежуточными цветами, а по краям делаем тонкую полупрозрачную полоску.
С ног на голову
Если выставить ограничение на количество цветов векторного изображения, то можно пойти по совершенно другому пути. Допустим, что у нас есть простая векторная одноцветная иконка:
Её можно «сжать» почти без потери качества с помощью Signed Distance Field. Суть заключается в том, что мы храним не саму текстуру, а информацию о расстоянии пикселей до границы иконки. Значение на границе обычно считается равным 0.5. Всё что больше считается «внутри» иконки. Всё что меньше — «снаружи». По факту неважно в какую сторону перевешивается граница — иногда можно сделать меньше 0.5 внутри и больше 0.5 снаружи. Для наглядности (чёрные иконки на белом фоне) я покажу именно такой вариант.
Размазанный таким образом игральный кубик выглядит вот так:
Отличие от обычного размытия заключается в том, что находя минимальное расстояние между текущим пикселем и границей, у нас в любом случае получится расчёт расстояния по нормали (минимальное расстояние от точки до прямой всегда определяется перпендикуляром). То есть градиенты на текстуре описывают направление нормали к ближайшей границе.
В интернете и, в частности, на хабре достаточно много статей про SDF, я приведу их в конце статьи.
На картинке хорошо видно различие в качестве между обычной текстурой и двумя вариантами SDF. При увеличении обычной картинки становятся явно видны размытости. Увеличивая же SDF текстуру, мы в любом случае получим резкие границы. Причём даже уменьшив размер текстуры в два раза, наличие артефактов остаётся почти незаметным (про увеличение качества сырой SDF текстуры можно написать отдельную статью). Артефакты, в отличие от обычной текстуры, проявляются в виде сглаженной лесенки на скошенных краях иконки. Это обусловлено тем, что пиксели идут ровно по горизонтали и вертикали, и при уменьшении размера изображения также уменьшается точность аппроксимации косой прямой с помощью двух перпендикулярных (напомню что мы аппроксимируем вектор нормали к границе).
Шейдер для отрисовки будет самую малость сложнее, чем простое чтение текстуры. В экспериментах я попробовал много разных вариантов, в т.ч. и вариант из статьи [2], в общем виде это выглядит примерно так:
Стоит отметить, что в данном случае RBG канал текстуры выбрасывается и в расчётах не участвует (к этому мы ещё потом вернёмся). Настраивать _Smoothing можно либо вручную под текущий размер текстуры на экране (но тогда будет та же проблема при увеличении, что и была в случае с отрисовкой через меши), либо использовать cg функцию fwidth, которая примерно оценивает размер текущего фрагмента относительно экрана и «подстраивает» сглаживание под относительный размер иконки на экране.
Поскольку основным ограничением метода SDF является необходимость «бинарности» (одноцветность) исходного символа, наиболее часто его применяют при отрисовке текста — настраивая и видоизменяя варианты обработки одной и той же SDF текстуры, можно создавать обводку, тень, размытие и т.д. [1]. Менее популярным способом использования SDF является отрисовка одноцветных иконок (как в случае с изображением игральной кости), но по большей части это просто частный случай текстового символа.
Ещё одним минусом подобного подхода является потеря резких граней и углов:
Слева — оригинальная текстура. Справа — SDF уменьшенного размера
И ещё пример с текстом из статьи [3]:
Решение проблем по мере поступления
Есть примеры реализации подобного алгоритма, сохраняющего острые углы [4][5]:
Краткая суть алгоритма заключается в следующем:
«сырой» SDF скругляет углы из-за того, что чем дальше от него пиксели, тем сильнее он скругляется. Происходит это из-за того, что к углу нельзя провести перпендикуляр (производная функции в этой точке не существует) — много пикселей будут считать расстояние по радиусу окружности, центром которой как раз и является угол. Этого можно избежать, если отследить все углы символа, проверив разрывы плавно идущей кривой. А затем, используя таблицу истинности, определить, должен ли быть закрашен квадрант угла или нет. То есть углы обычно закрашиваются пересечёнными SDF картами, записанными в разные каналы, а конечное значение пикселя считается по медиане векторов из трёх каналов.
Разумеется я не могу вместить всю статью на 90 страниц в один абзац, поэтому советую посмотреть её полностью [5].
Были и более ранние попытки сделать что-то подобное с пересечением разных полей раскиданных по каналам, но некоторые варианты не предполагают наличие хитрых возможностей добавления тени, обводки или увеличения толщины символа, в отличие от описанного примера (из-за того что фактически там не остаётся поля расстояний как такового).
Меньше каналов — больше точности
В твиттере есть товарищ, который всеми правдами и неправдами делает что-то подобное, но с одним каналом:
Если посмотреть разные ссылки в его твиттере, то можно наткнуться на некоторые варианты реализации. Насколько я понял, подход отличается от стандартного SDF тем, что не используется фактическое расстояние до границ (чтобы избежать того самого округления вокруг угла-центра), а используется немного переинтерпретированная фигура, углы которой продолжаются дальше. Это позволяет избавиться и от скругления углов и от нескольких каналов, упрощая шейдер, и уменьшая общее количество информации, требуемое на представление подобных фигур.
Также у этого товарища есть шейдер, который в реальном времени считает distance field для кривой безье на GPU, но там требуются десктопные вычислительные мощности даже для одной кривой (которая задаётся параметрически и формула её лежит «прямо в шейдере»). Если покрутить настройки и код, то можно посмотреть само поле расстояний без закрашивания и модуляции:
Общая суть у этих методов заключается в анализе кривой, определяющей границы символов.
Возвращаемся к истокам
Также можно пойти по третьему пути — не хранить растровую информацию о каком-либо символе, а рисовать, так скажем, «из печки» — напрямую из векторного представления кривых. Проблема в том, что относительно сложно передать информацию о кривых на графическую карту без потери производительности. Есть несколько статей, описывающих подобные методы:
Если кратко, то суть в следующем:
Разделяем символ на ячейки, для каждой ячейки делаем карту пересечений кривых с лучами, пущенными под разными углами и пересекающими эту ячейку. Смотрим количество пересечений и расстояние, на которых возникли эти пересечения. Данные о кривых хранятся в виде скомканной текстуры, в которой заданы координаты кривых безье. Одна кривая безье — это 3 или 4 параметра в зависимости от степени этой кривой. Выше 4го параметра кривые обычно не берут. Шейдер занимается тем, что в зависимости от текущей отрисовываемой ячейки и параметров текстуры, присутствующих на этой ячейке, считывает необходимые пиксели из референсной текстуры и использует их для восстановления аналитического вида кривой на GPU.
Не всё так радужно.
Минусом подобных подходов является использование относительно большого количества операций чтения текстуры. Я как-то имел дело с реалтаймовым рендерингом теней с tap blur размытием на мобильных устройствах, и любые Dependent Texture Reads (DTS — я не нашёл общепринятого аналога на русском) существенно ухудшали производительность. Если очень грубо — DTS возникают, когда координаты чтения текстуры становятся известны только во fragment shader, то есть непосредственно при отрисовке пикселя. Обычно высокая скорость чтения текстуры во fragment shader обуславливается тем, что конкретная интерполированная текстурная координата пикселя становится известна сразу после работы vertex shader, то есть видеокарта заранее читает нужный пиксель текстуры и отдаёт значение пикселя «бесплатно». Алгоритмы, поведение и степень трудозатрат определяется в первую очередь железом, на котором выполняются эти шейдеры. В OpenGL ES 3.0+ вроде как по большей части решается проблема производительности DTS, но на данный момент около половины мобильных устройств работает на OpenGL ES 2.0, поэтому пока надеяться на хорошее железо не стоит.
(источник от 6 февраля 2017)
Стоит отметить, что запатентованный Microsoft подход позволяет, используя 4 канала, кодировать цвет пикселей, находящихся в ячейке. И именно отрисовкой цветных векторных изображений я заинтересовался изначально.
Как жить дальше
У описанных выше методов есть следующие недостатки:
Поэтому у меня возникло желание предложить немного другой способ отрисовки разноцветной векторной графики, основанный на всё том же принципе SDF.
Вторая жизнь для SDF
SDF стал синонимом одноцветной отрисовки символов текста. Но если представить векторную картинку в виде набора одноцветных слоёв, то с помощью той же SDF текстуры, можно отрисовать векторную картинку любой сложности и цветности. То есть мы просто разделяем начальную картинку на набор одноцветных слоёв.
Пример — ящик из популярного набора от Kenney, разрезанный на слои, выглядит так:
Это внешний вид SVG файла. Можно заметить, что слои не перекрывают друг друга, а «стыкуются» между собой. При просмотре подобных векторных изображений через Inkscape становятся явно видны артефакты, присущие подобной стыковке этих слоёв:
Присутствие артефактов зависит от способа создания векторной графики, но пока возьмём именно этот вариант.
К действиям
Для каждого слоя сделаем свою SDF текстуру и выставим слои друг поверх друга в том же порядке, в котором они идут в SVG файле.
Слева направо — SVG Importer с включённым antialiasing, «слоёный» SDF, увеличенная начальная текстура. SVG Importer не смог нормально распарсить SVG из Inkscape, но суть не в этом.
Если сильно приблизить оба объекта, то различия выглядят примерно так:
Основным недостатком этого метода по сравнению со всеми другими является существенный ovedraw. Чтобы нарисовать эту коробку требуется 4 полноразмерных слоя, помещённых друг на друга, плюс небольшой квад для пятого слоя (маленькая чёрточка). В худшем случае overdraw будет прямопропорционален количеству слоёв векторной картинки. Чем выше разрешение устройства, тем медленнее будет работать рендеринг.
Но в отличие от большинства пакетов по парсингу SVG файлов в меши, заранее подготовленные текстуры занимают существенно меньше места. Scaleform в этом плане пошли дальше — они генерили все меши на лету при загрузке сцены, не забивая архив приложения заранее созданными файлами. Для сравнения, начальный размер коробки составляет 4 Кб текста, то есть заранее собранный со сглаживанием меш векторной картинки занимает в 11 раз больше места, чем сырой текст, описывающий эту векторную фигуру.
Варианты — тысячи их
Я также наткнулся на другой способ конвертации цветного изображения в SDF вид. [6] Суть заключается в использовании bit planes (бит-карт) изображения для цветов. Бит-карты раскладывают яркости цвета по битам.
То есть берутся по порядку биты яркости и кладутся в отдельную бинарную текстуру. Всего на один канал изображения нужно 8 текстур. То есть 24 текстуры на цветное изображение без прозрачности.
Если пойти дальше и представить каждую такую двоичную текстуру как 8ми битную SDF текстуру, то получается что для полноценного представления начального изображения потребуется 24 восьмибитных текстуры (а не 24 однобитных, которые получаются сразу после разложения на бит-карты).
Процесс восстановления начального цветного изображения из обработанных с помощью SDF бит-карт выглядит следующим образом:
Хотя алгоритм этот достаточно хитрый, на деле качество оставляет желать лучшего:
Артефакты появляются из-за того, что проблема потери точности при хранении уменьшенной копии SDF текстуры ухудшается разрезанием каналов цветов на побитовую составляющую. На мой взгляд, этот метод не особо применим уже по этой причине. Но ещё одним минусом является необходимость хранить 24 восьмибитных SDF текстуры на одну исходную цветную картинку.
Итоги
Нового полноценного решения «из коробки» пока предложить не могу, но есть идеи и попытки сделать кодировку SDF по палитрам с маркировкой контуров, что, возможно, позволит избавиться от хранения большого количества разных текстур для разных каналов и уменьшить overdraw.
Статья уже получилась очень большой, и мне пришлось существенно обрезать контент. Из того, что не рассказал: