webgl publisher что это

Начало работы с WebGL

WebGL позволяет веб-контенту использовать API, основанный на OpenGL ES 2.0, для визуализации трёхмерной графики без использования плагинов в HTML элементе canvas в браузерах, которые осуществляют его поддержку. WebGL программы состоят из кода управления, написанном на JavaScript и кода специальных эффектов (шейдерного кода), который выполняется на графическом процессоре. WebGL элементы могут быть смешаны с другими HTML-элементами и собраны с другими частями веб-страницы или фоном веб-страницы.

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

Подготовка к визуализации в 3D

Подготовка контекста WebGL

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

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

Создание контекста WebGL

Функция initWebGL() выглядит следующим образом:

Чтобы получить контекст WebGL для canvas, мы запрашиваем у элемента canvas контекст именуемый как «webgl». Если данная попытка завершается неудачно, мы пытаемся получить контекст, именуемый как «experimental-webgl». Если данная попытка также завершается неудачно, мы отображаем окно с предупреждением, позволяющим пользователю понять, что его браузер не поддерживает WebGL. Это всё, что необходимо сделать. На данном этапе мы будем иметь в переменной gl либо значение null (означающее, что контекст WebGL не доступен), либо ссылку на контекст WebGL в котором, мы будем производить отрисовку.

На данном этапе этого кода достаточно, чтобы успешно инициализировать контекст WebGL, и вы увидите пустой чёрный блок, готовый к заполнению контентом.

Если ваш браузер поддерживает WebGL, то вы можете посмотреть результат выполнения приведённого выше кода, щёлкнув по этой ссылке.

Изменение размера контекста WebGL

Источник

WebGL на Unity3d — двенадцать проблем при сборке проекта

Не так давно в Unity вышла из беты возможность создания проектов для WebGL. Делюсь своим опытом сборки под эту платформу большого игрового проекта.

Disclaimer: Статья только для тех, кто сам собирается сделать что-то подобное — она очень техническая и использует специфическую для Unity терминологию.

1. Загрузка типа через reflection

Первая проблема: вот такой простой код будет работать неправильно:

Он работает, но тип возвращается неправильный и «пустой». Проблемы начинаются при работе с этим типом — почти все его методы возвращают пустые значения. Чтобы всё стало правильно, надо писать так:

Вот тут заявлено, что это — ожидаемое поведение.

2. Динамическая загрузка ресурсов

Следующая проблема возникает при использовании методов Resources.Load или Resources.LoadAll. Эти методы сказочно долго работают. Для однопоточного браузера это легко становится критичным. Динамическую загрузку ресурсов этими и схожими методами лучше не использовать вовсе. Где возможно, надо менять её на статическую (заранее проставлять ссылки на нужные префабы). Разница во времени загрузки на моем проекте доходила до десяти секунд.

3. Синхронизация файловой системы

Если вы пользуетесь файловой системой, то нужно знать, что она реализована как wrapper над базой данной, встроенной в браузер. Но самое главное — синхронизация браузера с этой базой происходит только по прямой яваскриптовой команде:

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

2) Вызываем это из c#:

4. Инициализация WebGL и компиляция шейдеров

При старте приложения существенное время может занимать инициализация WebGL. Это очень важно, потому что данное время учитывается браузером в общее время непрерывной работы скрипта, которое ограничено (в Firefox, например, оно 10 секунд по умолчанию).

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

1) Минимизировать число различных шейдеров, используемых в проекте. Часто проект использует почти одинаковые шейдеры, которые приехали в него из разных покупных ассетов.

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

5. Кэш Firefox

Если вы собираетесь отлаживать ваш проект, используя локальный сервер и Firefox, то столкнётесь с тем, что браузер неверно кэширует часть WebGL проекта.

Я делаю и запускаю версию 1. Она работает. Затем делаю версию 2. Запускаю — падает с непонятной ошибкой.

Лечится это ручной чисткой кэшей FF по адресу:

1) C:\Users\<ИМЯЮЗЕРА>\Application Data\Mozilla\Firefox\Profiles\<ИМЯПРОФИЛЯ>\storage\temporary\

Тут можно удалять вообще всё.

2) C:\Users\<ИМЯЮЗЕРА>\Application Data\Mozilla\Firefox\Profiles\<ИМЯПРОФИЛЯ>\storage\default\

Тут надо удалить только ваш сайт. Например

Замечание: Это происходит только при работе с HTTP сервером. Если запускать проект из файлов ошибки не происходит, поскольку кэши для каждого пути к файлам — разные. А вот для сервера один кэш, независимо от пути.

6. Script does not respond for a long time. Stop it?

Firefox спросит у вас об этом почти наверняка. Если проект большой, то может спросить и несколько раз.

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

1) Идет загрузка данных браузером с сервера. Тут мы ничего ускорить не можем, но это время браузер и не ограничивает.

2) Идет декомпрессия данных.

Decompressed Release/w69.memgz in 100ms. You can remove this delay if you configure your web server to host files using gzip compression. UnityLoader.js:1:775
Decompressed Release/w69.jsgz in 391ms. You can remove this delay if you configure your web server to host files using gzip compression. UnityLoader.js:1:775
Decompressed Release/w69.datagz in 2764ms. You can remove this delay if you configure your web server to host files using gzip compression.

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

Successfully compiled asm.js code (total compilation time 9088ms; stored in cache)1 56937f89-a8fd-4b65-94aa-453e33be78d8

Может занимать 5-10 сек, но тоже не ограничивается браузером, так как код игры еще не стартовал.

4) А вот дальше стартует код игры

И, с точки зрения браузера, код Unity (такой, как инициализация WebGL) не отличается от кода самой игры. Причем выполняются они одним куском, подряд. Поэтому тут за 10 секунд должна пройти и инициализация WebGL и пользовательский код. Учитывая, что время инициализации WebGL обычно не может быть сокращено сильнее, чем до 4-5 секунд на хорошем компьютере, тут лучше не рисковать и снизить время инициализации пользовательского кода до минимума. В идеале, он вообще ничего не должен делать. А как же тогда инициализировать игру? Её можно отложить. Например, так:

Смысл — сразу вернуть управление браузеру и через 0.1 секунду запускать свой код. После такого трюка браузер начнёт отсчёт 10 секунд заново. Соответсвенно, если инициализация у вас длинная, то можно и далее разбивать её на части таким же образом (хотя лучше постараться сократить — пользователь не любит ждать).

И последнее: ограничение на 10секунд непрерывного исполнения скрипта применяется не только во время инициализации.

7. Использование бандлов

При использовании asset bundles важно помнить, что они должны быть загружены с того же сервера, что и сама игра. Иначе работать не будет из-за нарушения single origin policy.

Второй момент — чтобы избежать задержки на декомпрессию бандла после загрузки лучше при создании бандла использовать не gz (по умолчанию), а lz4:

8. Ограничение на 512 mb

На моей машине ни один браузер не был в состоянии выделить игре более 512mb. Хотя памяти на машине много. Полагаю, что не нужно выделять играм, собираемым под WebGL, больше памяти, чем 512mb. И саму игру нужно делать так, чтобы ей этого хватало. В идеале вообще оставить 256mb которые стоят по умолчанию.

9. Strip engine code

Strip engine code — это галочка в настройках сборки, которая заставляет Unity выбрасывать из сборки неиспользуемые системные скрипты.
Это позволяет значительно сокращать итоговый объем сборки. Проблема здесь в том, что если какой-то код используется только ассетами, попавшими в бандл, он тоже будет выброшен. А итоговая сборка работать не будет. Причем exception будет абсолютно непонятный.

1) Если получили непонятный exception, попробуйте собрать убрав эту галочку;
2) Можно прямо использовать скрипты, нужные ассетам из бандлов в коде или использовать специальую возможность Unity — файл link.xml.

10. Developer builds — no fast builds!

Когда собираешь developer build есть возможность выбора между быстрой сборкой и быстрым исполнением. На самом деле быстрая сборка занимает почти такое же (громадное) количество времени и при этом, на большом проекте часто совсем не работает из-за нехватки памяти. Лучше её не использовать.

11. Crunched textures

Для проектов под WebGL всегда используйте crunched texture. Иначе объем игры будет неприлично большим для web приложения.
Чтобы не выставлять тип каждой текстуре вручную, можно использовать вот такую технику (нужно перегрузить метод OnPostprocessTexture).

А двенадцатой пробемы нет, просто «двенадцать проблем» звучит лучше, чем одиннадцать.

UPDATE от 1го июня 2017г:

Двенадцатая проблема все-таки есть. Связана она с передачей строковых параметров между Unity и WebGL плагинами. Передача строки из Unity в webgl работает нормально. А вот наоборот — не всегда.
Unity предлагает использовать такой вот snippet:

var buffer = _malloc(val.length + 1);
writeStringToMemory(val, buffer);

Здесь — val — строка в javascript.
Это работает до тех пор, пока длина строки совпадает с количеством байтов в ней. Как только в строке встречаются неоднобайтовые (например, русские) символы, этот код приводит к записи за пределы выделенной памяти, что выражается в случайных крэшах вашего приложения в произвольных местах.

Так что либо используйте encode, чтобы ваши строки использовали лишь символы из latin1, либо перепишите этот snippet так, чтобы он использовал количество байт, а не символов в строке.

Источник

Есть ли жизнь без WebGL 2.0?

WebGL 2.0 вышел в далёком 2017ом году, принёс графический стек OpenGL ES 3.0 (2012го года), и, казалось бы, все современные браузеры давно должны были его поддерживать. Однако, среди лидеров затесались отстающие, и пользователи Safari до сих пор (начало 2021го) вынуждены ограничиваться возможностями WebGL 1.0, опубликованным в 2011ом году на основе OpenGL ES 2.0.

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

Некоторое время назад, графический движок C++ фреймворка Open CASCADE Technology (OCCT) обзавёлся поддержкой PBR (основанной на физике освещению) модели материалов металл-шероховатость (metal-roughness). Продвижение формата glTF 2.0, известного как “JPEG для 3D”, способствовало выводу этой модели материалов как стандарта обмена между графическими движками.

webgl publisher что это. Смотреть фото webgl publisher что это. Смотреть картинку webgl publisher что это. Картинка про webgl publisher что это. Фото webgl publisher что это

PBR освещение требует существенно больше вычислительных ресурсов по сравнению с устаревшими эмпирическими моделями Гуро/Фонга времён OpenGL 1.1. Поэтому неудивительно, что реализация PBR в движке была изначально написана на основе относительно “современного” графического стека OpenGL 3.0 (выпущенного в 2008ом году!) и адаптированного под его мобильную версию OpenGL ES 3.0.

При этом вполне очевидно, что ограничение WebGL 1.0 связаны именно с программной стороной, ведь графические процессоры мобильных устройств Apple давно считаются относительно производительными, да и OpenGL ES 3.0 поддерживается на iOS нативными приложениями.

Мини-вызов: OCCT PBR на WebGL 1.0

Несмотря на многочисленные свидетельства того, что Safari вот-вот обзаведётся поддержкой WebGL 2.0, текущие пользователи по-прежнему страдают от его отсутствия (ну или радуются экономии заряда батареи). Некоторые графические движки прямо заявляют, что не поддерживают PBR освещение без WebGL 2.0, однако мне стало любопытно, реалистично ли запустить PBR на WebGL 1.0 и с какими ограничениями.

Впрочем, конечной, целью была выбрана не поддержка “голого” WebGL 1.0, а запуск PBR на современных устройствах iPad с доступными расширениями WebGL. Вот список таких расширений для устройства iPad ‘2020 (Apple A12 Bionic) на iOS 14.4 / Safari:

Отладка вёб-приложения в мобильном браузере удовольствие весьма сомнительное, поэтому первым делом были подобраны альтернативные конфигурации с WebGL 1.0:

Отключение WebGL 2.0 в скрытых опциях Firefox.

Управляется опцией “ webgl.enable-webgl2=false ” на странице “ about:config ”.

Предоставляет аппаратно-ускоренную реализацию WebGL 1.0, допускающую некоторые отклонения от WebGL 1.0 спецификаций на железе уровня WebGL 2.0.

Поддерживает вывод JavaScript консоли.

Отключение WebGL 2.0 в опциях сборки Emscripten.

Управляется флагом сборки “ MAX_WEBGL_VERSION=1 ”.

Предоставляет аппаратно-ускоренную реализацию WebGL 1.0.

Поддерживает JavaScript консоль (в десктопных браузерах).

Отключение аппаратного ускорения в браузерах на движке Chromium в паре с опцией сборки “ MAX_WEBGL_VERSION=1 ”.

Предоставляет программную реализацию WebGL 1.0, которая обычно ближе придерживается к спецификациям по сравнению с аппаратно-ускоренными реализациями.

Поддерживает JavaScript консоль (в десктопных браузерах).

Сборка Draw Harness на десктопе с опцией OpenGL ES, реализованной библиотекой ANGLE.

Использует ту же реализацию OpenGL ES, которую используют десктопные браузеры.

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

Запуск в браузере Safari на macOS.

Предоставляет аппаратно-ускоренную реализацию WebGL 1.0.

Поведение на Apple M1 (ARM64) очень близко в iPad, но есть расхождения!

Поддерживает вывод JavaScript консоли.

Запуск в браузере Safari на iOS.

Предоставляет аппаратно-ускоренную реализацию WebGL 1.0.

Нет JavaScript консоли.

Наиболее упрямыми реализациями оказались программный WebGL, реализуемый средствами библиотеки ANGLE, а также реализация OpenGL поверх Metal от Apple. Там где CG компилятор NVIDIA не скажет ни слова, драйвер AMD мягко предупредит в логе компиляции шейдера, OpenGL реализация Apple не оставит безобразие без внимания и ошибкой скажет, что такой функции в GLSL 110 нет и появилась она только в GLSL 120!

Портирование кода PBR на WebGL 1.0 было встречено следующими проблемами:

Проблема #1: текстурные форматы GL_RG32F / GL_RG16F не поддерживаются iPad + WebGL 1.0 (расширение GL_EXT_texture_rg недоступно).

Проблема #2: текстуры формата GL_RGBA32F не поддерживают фильтрацию на iPad + WebGL 1.0. iPad не поддерживает расширение GL_OES_texture_float_linear, однако нефильтруемые текстуры с плавающей запятой поддерживается через расширение GL_OES_texture_float. В тоже время, iPad поддерживает расширение GL_OES_texture_half_float_linear, так что текстуры с плавающей точкой половинчатой точности поддерживают фильтрацию.

Проблема #3: текстуры формата GL_RGBA16F могут быть загружены напрямую из данных плавающей запятой одинарной точности в случае с OpenGL ES 3.0 / WebGL 2.0, однако WebGL 1.0 + GL_OES_texture_half_float не допускает этого.

Проблема: в текстуру формата GL_RGBA32F нельзя производить отрисовку через FBO на iPad + WebGL 1.0. iPad не поддерживает расширение WEBGL_color_buffer_float.

Проблема: iPad + WebGL 1.0 не допускают отрисовку в мип-уровни, отличные от нулевого (расширение GL_OES_fbo_render_mipmap не поддерживается).

PBR GLSL программы полагаются на явное задание мип-уровня текстуры, в зависимости от шероховатости материала.

Проблема #2: GLSL 100 es не предусматривает синтаксиса для инициализации массива констант.

Проблема #3: GLSL 100 es не допускает неконстантные выражения для определения индекса (non-constant index expressions).

Буфер цвета sRGB и кубическая карта окружения.

Проблема #2: ужасно медленная генерация мип-уровней для sRGB текстур на WebGL 2.0 (5 секунд!).

Поиск решений

webgl publisher что это. Смотреть фото webgl publisher что это. Смотреть картинку webgl publisher что это. Картинка про webgl publisher что это. Фото webgl publisher что это

Без функции textureCubeLod() в шейдере практически невозможно реализовать корректное поведение PBR освещение с разными уровнями шероховатости, но к счастью, все тестируемые реализации WebGL 1.0 поддерживали расширение GL_EXT_shader_texture_lod, активируемое в GLSL шейдере кодом:

webgl publisher что это. Смотреть фото webgl publisher что это. Смотреть картинку webgl publisher что это. Картинка про webgl publisher что это. Фото webgl publisher что это

Ранние версии GLSL просто не предусматривали синтаксис для инициализации массива констант:
> const float aSHBasisFuncCoeffs[9] = float[9] < 0.0, 1.0, 2.0, … >;

“Non-constant index expressions are disallowed”. Программа запекания PBR карт использует такие конструкции:
> int anIndex = int(gl_FragCoord.x);
> float aCoef = aSHCosCoeffs[anId] * aSHBasisFuncCoeffs[anId];

Ограничения GLSL 100 es приводят к написанию следующего ужасного кода с использованием if/else.
> if (anId == 0) < aCoef = aSHCosCoeffs[0] * aSHBasisFuncCoeffs[0]; >
> else if (anId == 1) < aCoef = aSHCosCoeffs[1] * aSHBasisFuncCoeffs[1]; >
> else if (anId == 2)

Большинство ограничений языка шейдеров GLSL 100 es являются не более чем эхом графических процессоров прошлого, не поддерживающих ветвление. И хотя синтакс GLSL заделывался на будущее, первая версия требовала написание циклов и условий ветвлений, которые могли быть тривиально раскручены (trivially unrolled) компилятором, т.к. графические процессоры того времени иного варианта просто не поддерживали.

sRGB текстуры

Но даже в случае с WebGL 2.0, формально поддерживающим генерацию мип-уровней sRGB текстур, данная функциональность реализована чудовищно медленной. Генерация мип-уровней кубмапы размером 2048x2048x6 выполняется 5 секунд на быстром десктопном компьютере! При этом тот же самый код отрабатывает за считанные доли секунд при использовании нативной OpenGL / OpenGL ES реализации вместо браузера.

Послесловие

В результате потраченных усилий наконец-то удалось увидеть PBR материалы посредством графического движка OCCT в Safari на iPad c контекстом WebGL 1.0. Конечно, тестируемое устройство относится к относительно новому поколению (iPad ‘2020, основанному на Apple A12 SoC анонсированной в 2018ом году), но есть надежда на то, что более старые устройства Apple также справятся с задачей.

webgl publisher что это. Смотреть фото webgl publisher что это. Смотреть картинку webgl publisher что это. Картинка про webgl publisher что это. Фото webgl publisher что это

В этом контексте, отказ Microsoft от поддержки устаревших движков вроде Internet Explorer и Microsoft Edge Legacy (базирующимся на не-Chromium движке) ощущается как свежий воздух для вёб-разработчика, измученного проблемами совместимости. Хотя исчезающе малое количество конкурирующих полноценных вёб-движков не может не настораживать (Mozilla Firefox, Chromium, Safari/WebKit) и опасаться за будущее открытых вёб-стандартов в мире, где один браузер станет бесконтрольно доминировать.

Стратегия Apple по удержанию экосистемы iOS под колпаком и не пускать решения конкурентов лишает пользователей системы собственного выбора. Многочисленные слухи свидетельствуют, что измученная экспериментальная поддержка WebGL 2.0 в движке WebKit вот-вот перестанет быть экспериментальной (в том числе благодаря переходу на реализацию OpenGL ES библиотекой ANGLE, которая уже давно используется другими браузерами), хотя сроки, как обычно, остаются неизвестными.

Оригинальную публикацию на английском можно найти здесь.

Источник

Основы WebGL: разбираемся в магическом коде и заливаем на хостинг

Авторизуйтесь

Основы WebGL: разбираемся в магическом коде и заливаем на хостинг

webgl publisher что это. Смотреть фото webgl publisher что это. Смотреть картинку webgl publisher что это. Картинка про webgl publisher что это. Фото webgl publisher что это

WebGL — технология, которая «создает магию» в 2D-canvas’е HTML5. Рассказываем, как за счет градиента добиться такого интересного 3D-эффекта, как выпуклость, не используя дополнительных библиотек и подробно объяснив всю «магию». По завершению работы с кодом мы зальем наш проект на хостинг GPDHOST, чтобы вы могли поделиться результатом со знакомыми.

Начнем с примера: нарисуем прямоугольник на экране. Этот код должен срендерить прямоугольник с градиентом:

На самом деле, код рисует два треугольника, X и Y координаты каждого пикселя используются как R и G значения цвета, а цвета внутри треугольников экстраполируются и в результате получается прямоугольник с градиентом.

Что происходит?

О шейдерах

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

Как работает написанный выше код

JS-код начинается с простой инициализации и начальной загрузки: получения canvas, получения gl-контекста и т.д.

Сначала мы компилируем оба шейдеры в одну «программу»:

После компиляции проверяем, скомпилировались шейдеры или нет. Вы можете использовать что-то вроде:

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

Далее создается буфер из точек, которые мы будем использовать в качестве параметров для рисования. Мы помещаем эти точки в буфер и говорим WebGL, как их интерпретировать:

Теперь мы сообщим WebGL, как использовать эти точки:

Здесь мы связываем каждую точку с a_post и переводим каждые два числа в число с плавающей запятой.

Как WebGL «рисует»

Метод drawArrays работает с буфером, который мы подготовили: рисует из треугольник из трех пар координат.

На самом деле мы всего лишь сообщаем WebGL, что нужно нарисовать те 6 точек (3 на каждый треугольник) и экстраполировать цвета между каждой, чтобы получить градиент. Та как мы рисуем три треугольника, они заполняют всю область просмотра. Никто реально не рисует прямоугольники, а составляет их из треугольников — это полезно для простоты и оптимизации.

Вот так будет выглядеть результат выполнения нашего кода:

webgl publisher что это. Смотреть фото webgl publisher что это. Смотреть картинку webgl publisher что это. Картинка про webgl publisher что это. Фото webgl publisher что это

Давайте теперь поделимся своим успехом с миром и зальем наше творчество на хостинг!

Размещение проекта на хостинге

После получения доступа к контрольной панели хостинга, можете переходить к размещению веб-страницы с JS-кодом на сайте. В разделе «Quick Server Logins» кликните по имени выбранного вами домена, и далее в «Quick Shortcuts» выберите пункт «File Manager». Вам откроется такое окно:

webgl publisher что это. Смотреть фото webgl publisher что это. Смотреть картинку webgl publisher что это. Картинка про webgl publisher что это. Фото webgl publisher что это

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

Источник

WebGL для всех

webgl publisher что это. Смотреть фото webgl publisher что это. Смотреть картинку webgl publisher что это. Картинка про webgl publisher что это. Фото webgl publisher что это

Идея данной статьи родилась после нескольких мучительных недель изучения WebGL. На личном примере выяснилось, что люди, не сталкивающиеся до этого с 3D-графикой, имеют в основном ошибочные представления о работе данной технологии. К тому же была проблема с поиском информации в интернете.

WebGL, в отличие от Javascript, имеет высокий порог вхождения, его до сих пор мало кто использует, а ещё меньше тех, кто об этом пишет. Большинство руководств или статей перепрыгивают сразу на использование какой-нибудь библиотеки. Но мы-то с вами знаем, что большие универсальные инструменты не всегда пригодны для наших задач или, возможно, делают это на неприемлемом уровне: проигрывают в скорости, поставляются с ненужным багажом и т.д.

Этой статьёй хочется облегчить порог вхождения в чистый WebGL, дать начальное представление и подсказать, куда двигаться дальше.

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

WebGL основан на OpenGL ES 2.0, который, в свою очередь, является специальной версией для работы на мобильных устройствах. Спецификация WebGL была выпущена в 2011 году, разрабатывается и поддерживается некоммерческой организацией Kronos Group, сайт которой частенько лежит, что ещё более усложняет изучение. Известно, что в настоящее время идёт разработка спецификации версии 2.0.

webgl publisher что это. Смотреть фото webgl publisher что это. Смотреть картинку webgl publisher что это. Картинка про webgl publisher что это. Фото webgl publisher что это
Статистика поддержки WebGL разными браузерами с сайта caniuse.com

WebGL доступен в большинстве современных браузеров и поддерживается у 83% пользователей. Приятным бонусом разработки на WebGL является то, что вы будете поддерживать только современные браузеры и забудете о кошмарах ECMAScript 3.

Если вы думаете, что WebGL рисует 3D, вы ошибаетесь. WebGL ничего не знает о 3D, это скорее низкоуровневый 2D API, и всё что он умеет делать, это рисовать треугольники. Но он умеет рисовать их очень много и очень быстро.

Хотите нарисовать квадрат? Пожалуйста, соедините два треугольника. Нужна линия? Без проблем, всего лишь несколько последовательно соединенных треугольников.

Как нарисовать треугольник

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

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

Шейдер — это программа, выполняемая на видеокарте и использующая язык GLSL. Этот язык достаточно простой, и его изучение не представляет проблемы.

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

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

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

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

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

webgl publisher что это. Смотреть фото webgl publisher что это. Смотреть картинку webgl publisher что это. Картинка про webgl publisher что это. Фото webgl publisher что это
Если вершинный шейдер определяет геометрию фигуры, то фрагментный — её цвет

Как уже было сказано выше, код шейдеров пишется на языке GLSL. Рассмотрим код шейдеров для треугольника:

Пример вершинного шейдера:

Пример фрагментного шейдера:

Код состоит из переменных и главной функции, возвращающей основной результат работы шейдера: gl_Position передаёт координаты, а gl_FragColor устанавливает цвет.

webgl publisher что это. Смотреть фото webgl publisher что это. Смотреть картинку webgl publisher что это. Картинка про webgl publisher что это. Фото webgl publisher что это
Значения varying переменных внутри треугольника вычисляются
на основе значений этих переменных в вершинах

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

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

Для связывания двух типов шейдеров вместе используется шейдерная программа:

Если uniform-переменные связываются напрямую с переменными из js, то для атрибутов нужно использовать ещё одну сущность — буферы. Данные буферов хранятся в памяти видеокарты, что даёт значительный прирост в скорости рендеринга.

Создадим аналогичным образом буфер цветов. Цвет указываем для каждой из вершин в формате RGB, где каждая компонента цвета от 0 до 1:

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

Наш треугольник готов:
webgl publisher что это. Смотреть фото webgl publisher что это. Смотреть картинку webgl publisher что это. Картинка про webgl publisher что это. Фото webgl publisher что это
Полный код примера можно
посмотреть здесь

Как я и говорил, цвет пикселей внутри треугольника линейно интерполируется между разноцветными вершинами. Мы смогли нарисовать самую простейшую фигуру с помощью WebGL и познакомились с шейдерами и буферами. Перейдём к следующему этапу.

Как нарисовать куб и заставить его вращаться

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

webgl publisher что это. Смотреть фото webgl publisher что это. Смотреть картинку webgl publisher что это. Картинка про webgl publisher что это. Фото webgl publisher что это

Нам придётся прописать каждую вершину каждого треугольника. Есть способы использовать более короткую запись, но для начала сделаем по-простому:

Положение треугольника в пространстве задавалось с помощью вектора размерности три. Но фигура может не только менять положение, она может ещё вращаться и масштабироваться. Поэтому в трёхмерной графике используются не вектор положения, а матрица.

Известно, что матрица поворота в трёхмерном пространстве задаётся с помощью матрицы размером 3×3. К этой матрице добавляется вектор положения, таким образом, в итоге используется матрица 4×4.

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

Чтобы отрисовать трёхмерный объект, нам нужно ввести понятие камеры. Камера, как и любой объект, имеет своё положение в пространстве. Она также определяет, какие объекты будут видны на экране, и отвечает за преобразование фигур так, чтобы на экране у нас создалась иллюзия 3D.

webgl publisher что это. Смотреть фото webgl publisher что это. Смотреть картинку webgl publisher что это. Картинка про webgl publisher что это. Фото webgl publisher что это
Перспектива куба на экране

За это преобразование отвечает матрица перспективы. C glMatrix она создаётся в две строчки:

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

Инициализация шейдеров происходит точно так же, как и в случае треугольника:

Чтобы куб не стоял на месте, а вращался, необходимо постоянно менять его положение и обновлять кадр. Обновление происходит по средствам вызова встроенной функции requestAnimationFrame.

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

Получаем вращающийся куб:
webgl publisher что это. Смотреть фото webgl publisher что это. Смотреть картинку webgl publisher что это. Картинка про webgl publisher что это. Фото webgl publisher что это
Полный код примера можно
посмотреть здесь

Мы научились рисовать простой куб, поняли, как заставить его вращаться, и познакомились с понятиями матрицы положения и камеры.

Как отлаживать

Поскольку при работе с WebGL часть программы исполняется на стороне видеокарты, процесс отладки значительно усложняется. Нет привычных инструментов в виде DevTools и даже console.log. В интернете есть множество статей и докладов на эту тему, здесь же приведу лишь основные способы.

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

Также есть специальное расширение для браузеров WebGL-Inspector. Оно позволяет отследить загруженные шейдеры, буферы, текстуры в видеокарту, и вызовы методов WebGL.

Ещё есть Shader Editor, в Firefox DevTools этот функционал уже встроен, а для Chrome есть расширение, которое позволяет редактировать код шейдеров прямо в процессе работы приложения.

Куда двигаться дальше

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

Источник

Добавить комментарий

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