Неожиданная удача, глиф “g” на шейдерах!

 
 
 

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

В качестве оптимизации можно было бы конечно один раз глиф отрисовать в рендер-таргет, а потом просто блит, но это равносильно предрасчету глифов и просто блиту, разве что не во время разработки, а при старте.

Поэтому аналитическую информацию решено было предрасчитать и “запечь” в текстуру, а потом ей только пользоваться. С учетом фильтрации текстур еще и практически бесплатная интерполяция. С помощью библиотечки Cairo удалось просчитать нужную аналитическую информацию и быренько наваять шейдер. Вот что получилось.

Буква “g” при разных приближениях:

g-1

g-2

g-3

g-4

Как видно контуры плавные даже при огромном увеличении. Задача минимум (а изначально это вообще была задача максимум) достигнуто. Но дальше, как говориться, “Остапа понесло”.

Контур (красный), кроме того еще и плавный:

g-glow

Тень (синяя), тоже плавная:

g-shadow

В принципе и тень и контур можно делать жесткими. Но плавными они эффектнее смотряться.

Ну и как обычно – чайник для антуража, плюс в этот раз еще и цветной куб. Так – эксперименты…

Ох уж этот Cairo!!!

 
 
 

Небольшая заметка. Может сэкономить кому-нибудь кучу времени. Понадобилось тут воспользоваться библиотекой Cairo, да еще чтоб png-шки с прозрачностью генерировать. Так вот, библиотека Cairo позволяет в формате ARGB32 использовать альфу, но только когда вы устанавливаете пиксель, то его нужно умножить на альфу. Иначе не получается.

Т.е. 50% красного будет выглядеть как 0×80800000 а не привычные 0x80ff0000

Первые рендеры шрифтов на шейдерах

 
 
 

Продолжаем работу над реализацией рендеринга шрифтов на шейдерах в движке. Удалось наладить экспорт глифов шрифта из SVG (который получается из TTF) в нужном формате. С учетом преобразования кривых Безье в дуги окружности. Сегодня наладил импорт нужного формата в движок и рендер на шейдерах. Пока правда много багов, но даже первые результаты вполне обнадеживают.

На картинках – красной каемкой обозначена область рендеринга глифа (простой прямоугольник из четырех вершин).

Звездочка, имеются артефакты, вызванные расчетом. В принципе чинятся – надо немного подтюнить математику:

shader_text_1

Буква М (перевернута, т.к. сама область рендеринга перевернута – ура 3D преобразованиям). Артефактов практически нет:

shader_text_2

А вот знак доллара малость подкачал. Где-то глобальная ошибка в математике. Скорее всего в преобразованиях:

shader_text_3

Чайник на фоне – это так – для антуража =)

Преобразование кривой Безье в набор дуг окружности

 
 

Для реализации визуализации шрифтов на шейдерах в движке потребовалось преобразование кривой Безье (кубической, квадратичной) в набор дуг окружности. Долго штудировал математику, просмотрел даже некоторые забугорные whitepaper’s, но красивого решения не нашел.

Исходные данные, кубические кривые:

B = { ( 0, 0 ), ( 0.25, 0.25 ), ( 0.75, 0.75 ), ( 1, 0 ) }

b3_1

B = { ( 0, 0 ), ( 0.25, 0.75 ), ( 0.75, 0.25 ), ( 1, 1 ) }

b3_2

B = { ( 0.25, 0.25 ), ( 0.75, 0.75 ), ( 0.25, 0.5 ), ( 0.75, 0.25 ) }

b3_3

Квадратичные кривые:

B = { ( 0, 0 ), ( 0.75, 0.75 ), ( 1, 0 ) }

b2_1

B = { ( 0, 0 ), ( 0, 1 ), ( 1, 1 ) }

b2_2

B = { ( 0.25, 0.25 ), ( 0.75, 0.75 ), ( 0.45, 1 ) }

b2_3

В итоге был найден достаточно простой рекурсивный алгоритм, которые аппроксимирует кривые. В результате получены следующие картинки.

Кубические кривые (в порядке предоставления входных данных):

b3_1_r

b3_2_r

b3_3_r

Квадратичные кривая (в порядке представления входных данных):

b2_1_r

b2_2_r

b2_3_r

На каждую кривую получается в среднем 5-10 дуг окружностей. Вполне допустимо.

Honda Quality

Наткнулся вот на такую картинку. За последние 25 лет 75% машин производства Honda до сих пор ездят по дорогам. Это рекорд.

honda quality