%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d0%b5-%d1%82%d0%b5%d0%ba%d1%81%d1%82%d1%83%d1%80%d1%8b-%d1%81-%d0%bf%d0%be%d0%bc%d0%be%d1%89%d1%8c%d1%8e-webglСегодня мы хотим показать вам, как создать некоторые реалистичные эффекты искажения с использованием частиц шейдеров в WebGL. Идея заключается в том, чтобы добавить тонкое анимированное искажение статического изображения и какой-нибудь текст. Обратите внимание, что в данном эффекте используются пиксельные шейдера, работа которых заключается в запуске функций для каждого пикселя в видимой области. Для того чтобы реализовать задуманное, нам необходимо задать позиции для пиксельных шейдеров на нашем макете.

 

Следует отметить, что технология достаточно сложная и может поддерживаться не всеми браузерами. Давайте посмотрим на несколько аспектов в демонстрации, чтобы понимать, о чем мы хотим вам рассказать в сегодняшнем уроке.

Шаг 1. Мираж

Суть этого эффекта является в создании эффекта искажения. Прежде всего, давайте посмотрим на то, как мы можем сделать, для начала возьмём простое изображение, а затем немного будем его искажать.

Данный прием нам необходим для получения цвета пикселя на текстуре к которой он относиться в пространстве и позиционировании.

distortion-normal

Теперь вместо того , чтобы просто получать пиксель от текущей позиции , хоть мы можем применить некоторые значения для класса position, мы будем использовать следующее правило для получения цвета с соседней позиции для пикселя:

В результате мы получаем следующее изображение:

distortion-slant

Теперь, чтобы получить простое но интересное искажение, мы вычисляем позицию, основанную на синусоиде.

sine

Здесь мы добавим к позиции (х) значение синусоида рассчитанного на основе позиции (у).

distortion-sine

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

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

Так что теперь мы можем послать необходимое время нашим шейдером для каждого кадра и использовать его для анимации по синусоиду.

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

distortion-map

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

Шаг 2. Глубина

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

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

both-maps-297x300

В коде, мы их относим к соответствующим каналам:

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

Шаг 3. Наполнение

Мы не можем реализовать содержимое HTML к canvas объекту - ни в WebGL , ни в ее 2D. Создание текста в canvas это сложно, и при загрузке растрового изображения ,текст читается достаточно плохо, и у него есть свои проблемы: ограниченное разрешение, размер файла.

Решение состоит в том, чтобы использовать SVG - мы можем сделать внешне загружаемым файлам SVG для canvas объекта, а затем использовать его в canvas в качестве текстуры. SVG файлы проще в обслуживании, легкие по сравнению с растровыми изображениями.

Это быстрый способ загрузить SVG и применить его к canvas:

Теперь прием с помощью которого мы можем облегчить размещение текстуры, которую мы только что создали для WebGL контейнера:

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

%d1%81%d0%be%d0%b7%d0%b4%d0%b0%d0%bd%d0%b8%d0%b5-%d1%82%d0%b5%d0%ba%d1%81%d1%82%d1%83%d1%80%d1%8b-%d1%81-%d0%bf%d0%be%d0%bc%d0%be%d1%89%d1%8c%d1%8e-webgl

И это наш конечный результат. Мы объяснили данный эффект на первом примере и подробно объяснили, но есть намного больше возможностей, в том числе эффектов искажения для воды, вы можете увидеть их в нашей демонстрации.

Вот и все. Готово!

Читайте также: