Вступление

Пока мы готовим статью о серверной стороне Graffiti, давайте рассмотрим другую тему: в нашем новом пошаговом руководстве мы показываем реализацию матричного эффекта с использованием GLSL. В Clash of Coins матрица используется как индикатор захвата определенной территории, как вы можете видеть ниже.

Мы также будем использовать PIXI.js, чтобы упростить рендеринг, чтобы мы могли сосредоточиться на самой важной части - написании шейдера. Чтобы следовать этой статье, вы должны понимать основные концепции рендеринга с использованием WebGL и иметь некоторые знания о шейдерах.

Препараты

Во-первых, нам нужна геометрия для рисования на экране. В этой статье мы используем Pixi.js v5, но вы можете выбрать любую другую библиотеку WebGL или даже не использовать ее вообще.

Нам нужно создать базовое приложение Pixi.js:

И теперь мы можем создать новую геометрию и добавить к ней два атрибута:

Для нашего матричного эффекта требуются UV-координаты, поэтому мы добавляем соответствующий буфер в геометрию. Неважно, к какой геометрии будет применен наш эффект, если у него есть действительные данные UV.

У нас также есть специальная текстура, содержащая отдельные символы, и мы используем ее для случайного выбора образцов. На этой текстуре каждый персонаж помещен в квадратик 16x16.

После загрузки текстуры мы должны убедиться, что для нее установлен режим обтекания REPEAT и отключены MIP-карты:

const texture = PIXI.Texture.from('font.png');
texture.baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT;
texture.baseTexture.mipmap = PIXI.MIPMAP_MODES.OFF;

На данный момент мы используем заполнитель для наших реальных шейдеров, чтобы у нас уже был какой-то результат на экране:

Имея шейдеры, мы уже можем создавать материал.

И, наконец, мы создаем сетку из геометрии и материала:

Вот какой результат вы можете получить на этом этапе:

Написание шейдера

Наш вершинный шейдер остался прежним, за исключением введения униформы для управления масштабом UV:

Нам также необходимо учитывать равномерность шкалы при установке значения vTextureCoord в функции main:

Далее нам нужно случайным образом отобразить разные символы из текстуры. Для этого мы используем функцию случайного выбора:

Теперь нам нужно создать функцию, которая действительно выбирает случайные символы. Во-первых, наш квад нужно разбить на маленькие плитки, и для каждой ячейки мы вычисляем локальные UV-координаты:

Это значение одинаково для всех пикселей в плитке, поэтому мы можем использовать его как начальное значение для случайной функции:

Мы также смещаем localUV на uTime униформу, чтобы со временем менять символы.

И, наконец, мы отбираем текстуру шрифта и возвращаем любой компонент vec4 (неважно, какой из них, поскольку текстура в оттенках серого):

Теперь нам нужна еще одна функция для добавления следов, идущих сверху вниз. Эта функция приводит к еще одному веществу с плавающей запятой, которое затем умножается на цвет текста.

Теперь мы можем вычислить псевдослучайный offset, используя положение плитки, а также заставить следы двигаться, используя uTime и uSpeed униформу:

Наконец, мы вычисляем цвет следа и фиксируем его до [0; 1]:

Теперь, когда обе функции заработали, мы можем добавить main():

Вот как выглядит окончательный список униформ, используемых в шейдерах:

Живой пример

Живой пример доступен здесь, а исходники проекта - в этом репозитории GitHub.

Дальнейшие чтения

  • Книга шейдеров - отличная отправная точка для изучения того, как работают шейдеры.
  • Shadertoy - место, где вы можете легко начать писать шейдеры без использования каких-либо библиотек и делиться ими.

Надеемся, вам понравилось наше руководство. Следите за нашей следующей статьей! И до скорой встречи в Clash of Coins!

Не забывайте подписываться на нас в социальных сетях!