Идея портирования Android-приложения на WebGL Сейчас WebGL поддерживается практически любым устройством и работает достаточно стабильно и быстро даже на мобильных устройствах, поэтому было очень интересно попробовать что-то реализовать с помощью этой технологии.
У нас уже есть большой опыт работы с OpenGL ES 2.0 в Android — мы создали довольно много различных живых 3D-обоев.
Мы создавали эти приложения без использования готовых сторонних движков (например, Unity) или высокоуровневых фреймворков для работы с OpenGL (таких как libGDX).
Поскольку код не обременен ограничениями сторонних фреймворков, приложения очень маленькие и быстрые, а также у нас есть возможность полностью оптимизировать рендеринг под нужды каждого приложения.
WebGL основан на OpenGL ES 2.0, поэтому процесс переноса обоев достаточно прост и понятен.
Фреймворк рендеринга
Как и в исходном коде Java, реализованы базовые классы.Базовый рендерер И БазовыйШейдер .
Было решено использовать классы ECMAScript 2015, поскольку такая нотация упрощает читаемость кода, а единственный браузер, не поддерживающий JS-классы, — это IE11. Базовый рендерер содержит код для создания контекста WebGL, инициализации, отслеживания изменения размера окна и т. д. Также он содержит пустые «заглушки» для рендеринга сцены.
БазовыйШейдер содержит код для компиляции и использования шейдеров.
Сам рендеринг сцены и загрузка данных для нее реализованы в BitcoinRenderer .
Загрузка готовых данных
Большинство движков и демонстраций WebGL загружают данные из файлов в формате JSON, OBJ или других форматах.С одной стороны это удобно — можно просто экспортировать модели из Blender или 3ds Max и использовать их в сцене.
Однако, с другой стороны, такой подход требует дополнительной обработки исходных данных на клиенте для создания буферов с данными, готовыми к использованию видеокартой.
Также данные в этих форматах часто содержат много избыточной информации, которая хоть и не используется, но все равно занимает большую часть исходного файла, что существенно увеличивает объем передаваемых данных.
В совокупности эти два недостатка приводят к тому, что зачастую даже простые демо-версии WebGL загружаются и запускаются довольно долго.
В Java-версии нашего фреймворка мы используем двоичные данные, готовые к загрузке непосредственно в буферы OpenGL, а в JS-версии мы применяем тот же подход. XMLHttpRequest уровня 2 поддерживает работу с двоичными данными в JavaScript. Для упрощения работы с XHR2 создан простой класс ДвоичныйЗагрузчикДанных .
Сорт Полная модель обеспечивает работу с сетками.
Метод нагрузка() загружает два буфера для модели — с индексами и данными (координатами вершин, UV-координатами и т. д.).
Эти буферы содержат двоичные данные, готовые к использованию видеокартой.
В классе также есть метод привязкабуферов () , который фактически связывает буферы и должен вызываться непосредственно перед глДравЭлементс() .
Сжатые текстуры в формате ETC1.
Для экономии видеопамяти в живых обоях мы используем различные сжатые текстуры.Наша платформа Java поддерживает форматы ETC1, ETC2, PVRTC и ASTC и использует наиболее подходящие текстуры с учетом возможностей конкретного устройства.
WebGL реализует только текстуры ETC1 и несжатые RGB. В OpenGL ES 2.0 ETC1 является обязательной частью стандарта и поддерживается на всех без исключения устройствах.
Однако в WebGL поддержка сжатия ETC1 не требуется, а наличие расширения необходимо проверять.
WEBGL_compressed_texture_etc1 .
Все настольные браузеры, кроме IE11 и Edge, поддерживают это расширение.
Для браузеров Microsoft необходимо использовать несжатые текстуры.
Проверить, какие форматы текстур поддерживает браузер, можно с помощью эта удобная страница .
Благодаря использованию текстур ETC1 мы используем гораздо меньше памяти, а также смогли ускорить процесс загрузки текстур.
Ведь несжатые текстуры перед попаданием в видеопамять необходимо сначала декодировать из исходного формата (PNG, JPEG, WebP, GIF и т.д.) в растровое изображение (RGBA или RGB, с альфа-каналами или без них) и только потом передавать в драйвер для загрузки в видеокарту.
Текстуры ETC1 не требуют никакой предварительной обработки — они уже готовы к непосредственному использованию видеокартой и поэтому загружаются гораздо быстрее.
Если говорить об экономии памяти, то, например, несжатая RGB-текстура размером 512х512 пикселей занимает 768 Кб, тогда как та же текстура ETC1 занимает всего 128 Кб.
Однако ETC1 не идеален и вызывает некоторые артефакты сжатия.
Эти артефакты практически незаметны на картах диффузии и освещения, но весьма заметны на картах нормалей (искажение в виде блоков пикселей 4х4) и картах отражений (неточная цветопередача).
Поэтому мы используем как сжатые, так и несжатые текстуры в зависимости от требований к качеству.
В Android загрузка текстур ETC1 очень проста — есть стандартная утилита ETC1Util , который выполняет всю работу по загрузке текстуры из файла PKM. В связи с тем, что WebGL не предоставляет никаких средств для загрузки сжатых текстур известных форматов, нам пришлось создать собственный загрузчик текстур ETC1 из файлов формата PKM. PKM — очень простой формат, он состоит из 16-байтового заголовка, за которым следуют двоичные данные, готовые к загрузке в видеокарту.
Более подробную информацию о названии можно найти Здесь И Здесь .
При написании кода получения размеров текстур мы столкнулись с определенным ограничением JavaScript. Эти значения сохраняются как 16-битные целые числа с прямым порядком байтов.
Однако используйте Int16Array получить эти числа не получится, потому что JavaScript не предоставляет возможности указать порядок байтов в буфере, поэтому мне пришлось читать байты, используя Uint8Array и вычислять 16-битные значения вручную из полученных пар младших и старших байтов.
Шейдеры
Приложение использует всего два шейдера: один для поверхности стола, другой для модели монеты.Табличный шейдер — это простая реализация карт освещения.
Он использует две текстуры: одна карта цветов (диффузная) для задания текстуры дерева, а вторая — карта освещения (lightmap).
Результатом шейдера является просто умножение цветов из этих текстур.
Шейдер монет более сложен, он содержит следующие функции:
- Карта сферического отражения (так называемое сферическое отображение или маткап)
- Карта освещения с улучшением цвета
- Нормальная карта
По сравнению с другими методами отражения сферическая карта имеет следующие преимущества: + Простой код шейдера и высокая производительность + Использование только одной текстуры + Текстура с отражением легко обрабатывается в графических редакторах, например Photoshop - Плохо работает на плоских поверхностях.
- Некоторое пространство текстуры тратится впустую (углы не используются) Самым большим преимуществом сферической карты является простота ее реализации.
Когда у вас уже есть нормаль, рассчитанная в экранном пространстве, вам просто нужно перенести ее в компонент (x;y), чтобы прочитать текстуру.
Выдержка из кода шейдера:
Это также приводит к величайшему недостатку данной методики: поскольку в расчетах участвует только нормаль экрана, большие плоские многоугольники будут залиты одним и тем же цветом (поскольку у них будет одинаковая нормаль по всей поверхности).vec4 sphereColor = texture2D(sphereMap, vec2(vNormal2.x, vNormal2.y));
А модель монеты состоит в основном из больших плоских поверхностей.
Чтобы бороться с этим недостатком, мы добавили карту нормалей и сделали ее максимально разнообразной: добавили шум, метки, цифры и т. д. Этот прием лишает модель гладких поверхностей и сферические отражения работают отлично.
При подсветке монет использовался дополнительный трюк.
Для затенения монет использовалась карта освещения.
Однако простое умножение цвета на карту освещения дает, хотя и более-менее правильный, скучный результат: затемненные области просто становятся темнее.
Помимо этого, в темных областях умножаем цвет сам на себя с помощью функции пау() .
Чем темнее карта освещенности, тем выше степень.
Это воспроизводит эффект «захвата» света в ограниченном пространстве и усиления его цвета за счет многократных отражений от металлических поверхностей.
В результате получается более реалистичная металлическая поверхность:
Результат
Готовое демо можно посмотреть здесь страница .Все источники доступен на GitHub и вы можете использовать их в своих проектах на условиях лицензии MIT. Теги: #andriod #webgl #шейдеры #GLSL #JavaScript #Разработка для Android #webgl
-
Google Reader Покинул Стены Google Labs!
19 Oct, 24 -
Sharpdevelop 3.0, Версия-Кандидат 1
19 Oct, 24 -
Распознавание Плоских Объектов Opencv 2.4
19 Oct, 24 -
Причины Экономического Кризиса
19 Oct, 24 -
«Админ» Может Быть Разным
19 Oct, 24