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

2014-09-17_0037

Мы уже рассказывали о том, как применить эффекты к изображениям при помощи canvas-фильтров и svg-фильтров. Давайте продолжим эту тему и рассмотрим webGl, как один из способов решать задачи фильтрации изображений в браузере.

WebGl – это браузерный API, наследующий принципы OpenGl и позволяющий использовать все прелести графического процессора (GPU) в браузере. Применимо к нашей задаче, основное достоинство WebGl – параллельная обработка всех пискелей изображения. В отличиие от Canvas, нам не нужно последовательно в цикле проходить по всему изображению и производить вычисления для каждого пикселя.

Дело в том, что у GPU (графического процессора), в отличие от CPU (центрального процессора), есть десятки тысяч ядер, которые могут работать параллельно.

Вот хорошее старое видео, наглядно поясняющее разницу в производительности между GPU и CPU.

разница в производительности между GPU и CPU.

Таким образом, используя WebGL для фильтрации изображений, мы отдаем каждый пиксель изображения отдельному ядру GPU, которое обрабатывает его по определенным нами законам. А законы эти описываются вот такими, на первый взгляд страшными кусками кода:

wtf?

precision mediump float;
varying vec2 position;
uniform sampler2D webcam;

void main() {
  vec2 pos = position;
  vec4 color = texture2D(webcam, pos);
  color.rgb = 1.0 - color.rgb;
  gl_FragColor = color;
}

Кто-нибудь знает, что это такое?
Правильно!
Это шейдер – кусок кода, соответствующий синтаксису GLSL (OpenGL Shading Language), который описывает алгоритм обработки каждого пикселя в GPU.

Шейдеры бывают:

  1. Векторными (Vertex Shaders) для работы с вершинами и полигонами в 3D.
  2. Пиксельными (Fragment Shaders) для работы с текстурами.

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

Не нужно бояться шейдеров.

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

color.rgb = 1.0 - color.rgb;

Весь остальной код – объявление переменных, описание источника изображения и значений на выходе.

Вот несколько особенностей языка GLSL:

  • Все значения находятся в диапазоне 0..1
  • GLSL позволяет получить доступ к компонентам векторов с помощью букв x, y, z, w и r, g, b, a. Таким образом, для двумерного изображения (vec2) можно использовать pos.x, pos.y. Для цвета (vec4) можно использовать color.r, color.g, color.b, color.a
  • GLSL поддерживает сокращенные записи. Например, color.rgb (работа сразу с красным, зеленым и синим каналом), color.rа (только красный канал и канал прозрачности) и т.д. Это просто приятный синтаксический сахар. Запись
    color.rgb = 1 - color.rgb;
    аналогична записи
    color.r = 1 - color.r; color.g = 1 - color.g; color.b = 1 - color.b;
  • Большинство функций GLSL может работать с несколькими типами входных параметров (float, vec2, vec3 и vec4).
  • Отладка GLSL – нелегкая задача, однако JS консоль Chroma довольно подробно сообщает об ошибках и указывает на строку шейдера, которая вызывает проблему.

A куда этот шейдер писать?

Вот здесь я могу точно сказать: не изобретайте собственный велосипед. WebGl имеет довольно высокий порог вхождения. Он призван решать задачи, на порядок сложнее фильтрации 2D изображений. Вы потратите много драгоценного времени на настройку и установку сцены, прежде чем сумеете применить тот самый шейдер. Это чем-то похоже на убивание мухи из пулемета.

Гораздо проще и приятнее использовать готовые библиотеки для фильтрации изображеий на основе WebGL. Давайте рассмотрим некоторые из них

Библиотеки


GLFX

GLFX – готовая библиотека, работающая с шейдерами для фильтрации 2D изображений.

glfx

js

var canvas = fx.canvas();
// convert the image to a texture
var image = document.getElementById('image');
var texture = canvas.texture(image);

// apply the ink filter
canvas.draw(texture)
.sepia(0.34)
.brightnessContrast(0.5, -0.5)
.ink(0.25)
.update();

Достоинства библиотеки glfx:

  • Красивый jQuery-подобный API с цепочками преобразований.
  • Возможность расширять библиотеку своими шейдерами.

WebGLImageFilter

WebGLImageFilter – красивая библиотека для фильтрации 2D изображений на базе WebGl с множеством предустановленных шейдеров.

webglimagefilters

WebGLImageFilter прост в использовании:

js

var filter = new WebGLImageFilter();
filter.addFilter('hue', 180);
filter.addFilter('negative');
filter.addFilter('blur', 7);
var filteredImage = filter.apply(inputImage);

Достоинства библиотеки WebGLImageFilter:

  • Красивый и понятный API.
  • Множество предустановленных фильтров.

Достоинства фильтрации изображений с WebGL

  • Очень, очень, очень быстро.
  • Есть несколько хороших плагинов.
  • Можно использовать готовые шейдеры написаные на языке GLSL для OpenGL за последние 14 лет (начиная c 2001 года)
  • Возможно использовать для живых видео-стримов.

Недостатки фильтрации изображений с WebGL

  • Для нестандартных операций порог входа достаточно высок.
  • Неполная поддержка webgl браузерами (в особенности мобильными):

svg-filters поддержка браузерами

В заключение

Фильтрация изображений при помощи шейдеров составляет ооочень малую часть возможностей WebGl. Нужно сказать, что он решает эту задачу на все 100%.

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

Метки: , , , ,

Оставить комментарий

Ваш email не будет опубликован. Обязательные поля отмечены *

*

* Copy This Password *

* Type Or Paste Password Here *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax

Вы можете использовать это HTMLтеги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Узнавай о новых статьях первым!

Спасибо за лайк в FACEBOOK
Подписывайтесь на новости вконтакте
Последние статьи от html5.by