Это демонстрация текста рендеринга непосредственно на графическом процессоре с использованием векторных контур, определенных шрифтом.
Контуры глифа преобразуются в список отдельных квадратичных кривых Безье (определяемых их контрольными точками), которые загружаются в GPU.
Для каждого глифа генерируется квадроцикл, и пиксельный шейдер определяет, находится ли каждый пиксель внутри или за пределами глифа. Для этого намоточное количество пикселя рассчитывается путем пересечения лучей с кривыми Безера. На каждом пересечении луч либо входит, либо выходит из заполненной области, как определено направлением кривой Безера относительно лучей. На каждом выходе число обмотки увеличивается на один, и при каждой входе число обмотки уменьшается на один. После рассмотрения всех пересечений обмотка будет ненулевым, если пиксель находится внутри контура.
Направление лучей не имеет значения для этого вычисления на извилистых числах, но математика может быть значительно упрощена с помощью лучей, параллельной оси x. Вычитая позицию выборки из контрольных точек кривых Безера, система координат смещается так, чтобы происхождение луча было в
Чтобы найти пересечения между лучами и одной кривой Безье, напомним, что квадратичная кривая Безера описывается следующей формулой (фон на кривых Безера см. Красоту и праймер):
Принимая только Y-компонент и применение условия
Который можно переставить в:
Так что его можно решить с помощью квадратичной формулы:
Замена
Квадратное уравнение может иметь ноль, одно или два решения. Кроме того, решение
На этом этапе были идентифицированы пересечения между кривой луча и безера, но они все еще должны быть классифицированы как вход или выход. Демо, предоставленное Добби
Следовательно, кривая Безье пересекает ось X в фиксированном направлении в каждом решении и в сочетании с соглашением для ориентации контура,
Другой подход к пониманию этих отношений состоит в том, чтобы заметить, что из-за различных признаков, используемых в решениях, а квадратный корень не связывает,
Если параметр
Противодействие вдоль направления луча реализуется с учетом окна размером с пиксель вокруг происхождения лучей. Если пересечение попадает в это окно, то обмотка изменяется только фракционно, чтобы вычислить покрытие пикселя. Дробный вес определяется расстоянием от левого края пикселя (это согласуется с лучами, указывающими вправо). Рассматривая отдельные разделы, можно увидеть, что это точно рассчитывает одномерное покрытие.
Обратите внимание, что теперь мы должны также рассмотреть перекрестки немного позади происхождения лучей, но реализация сначала вычисляет любое пересечение с оси X, а затем проверяет X-позицию, поэтому она не сильно меняется. Другой способ мышления об этом - это состояние
Для полного анти-альца мы можем использовать несколько лучей в разных направлениях (например, один вдоль оси x и один вдоль оси Y).
Этот вид техники подчиняется артефактам из ограниченной численной точности номеров с плавающей запятой. На изображении ниже показан экземпляр таких артефактов при полном увеличении (и зная, где смотреть). Тем не менее, я обнаружил, что эта реализация уже довольно численно стабильной. Любые оставшиеся артефакты могут быть устранены с использованием алгоритма Slug, который здесь не реализован из -за связанного патента.
Эта демонстрация также не реализует каких -либо оптимизации производительности (например, полоса) и может иметь высокое использование графического процессора в некоторых сценариях и при использовании очень сложных шрифтов.

Клонировать проект рекурсивно для инициализации подмодулей для зависимостей (или запустить git submodule update --init если вы уже клонировали репо):
git clone --recursive https://github.com/GreenLightning/gpu-font-rendering.git
cd gpu-font-rendering
# Note: CMake will create the build directory.
cmake -S . -B build
make -j8 --directory build
В Windows вы можете вместо этого использовать Cmake Gui и/или Visual Studio.
На Linux вам может придется установить дополнительные пакеты для разработки OpenGL (например, sudo apt-get install xorg-dev libgl1-mesa-dev для Ubuntu).
./build/main
Программа требует, чтобы каталоги fonts и shaders были в текущем каталоге для загрузки своих ресурсов. Если у вас есть только черное окно , это, скорее всего, проблема. Проверьте свой рабочий каталог и проверьте консоль на наличие ошибок.
Протестировано на Windows 10, MacOS Monterey и Ubuntu 22.04.