Недавно был выпущен WebVR API версии 1.1, а проект 2.0 находится в стадии разработки. По моему мнению, внедрение WebVR во все популярные браузеры — вопрос времени. В сегодняшней статье я расскажу подробнее о среде разработки и процессе создания приложений с использованием WebVR.
Сначала стоит отметить, что WebVR представляет собой способ использования браузера для просмотра виртуальной реальности (VR) и уже стал открытым стандартом. Он предоставляет JavaScript API, который позволяет разработчикам получать информацию о входах устройств VR и использовать её для изменения положения пользователя в виртуальном пространстве, его зрения и поведения.
Вот какую поддержку имеют основные платформы VR и браузеры:
Платформа VR | Поддержка браузерами |
---|---|
Google Cardboard | Chrome, Браузер VR компании Baidu |
Daydream | Chrome |
Samsung Gear VR | Oculus Carmel или Samsung Internet |
Oculus Rift | Firefox или экспериментальная ветка Chromium |
HTC Vive | Firefox или экспериментальная ветка Chromium или Servo |
К сожалению, опыт использования WebVR доступен пока только на устройствах Android и Windows. Однако это не мешает нам разрабатывать и тестировать приложения на Mac и Linux.
### Настройка среды разработки для WebVR
Поскольку WebVR-приложения должны работать на устройствах VR, стоимость которых может быть высока, ниже представлено решение для тестирования WebVR-приложений на компьютере.Первым шагом является запуск веб-сервера для статических страниц WebVR. Для этого можно установить расширение Web Server for Chrome, либо использовать Node.js или выложить код на GitHub.
Это расширение позволяет эмулировать взаимодействие пользователя с устройствами VR.
Для приложений уровня Google Cardboard.
На данный момент поддержка WebVR находится в раннем экспериментальном этапе. Вам потребуется последняя версия Chrome Beta. После установки вам нужно будет включить поддержку WebVR в настройках браузера, открыв chrome://flags#enable-webvr
, нажав "Enable" и перезапустив Chrome.
Это VR-сервисы от Google для пользователей Cardboard и Daydream, предоставляющие возможность запуска окон в режиме VR, как показано ниже.
Наконец, вы можете открыть страницу с примерами WebVR в Chrome для проверки правильности установки.
###### 3. Отладка с помощью инспектора Chrome
Чтобы отладить разработанные вами WebVR-страницы через мобильный браузер Chrome, откройте
chrome://inspect
в Chrome на вашем компьютере. Подробнее можно узнать из руководства удалённой отладки устройств Android.
После завершения конфигурирования среды разработки WebVR мы можем приступить к работе над проектами WebVR.
Разработка приложений WebVR основана на технологии WebGL, которая позволяет создавать и выполнять 3D-графику в браузере. Она следует спецификациям OpenGL ES и использует язык GLSL для управления GPU и выполнения вершинных и пиксельных шейдеров.
В сцене WebGL трёхмерные объекты создаются путём применения матриц преобразования, что приводит к формированию двумерного изображения на экране. Процесс матричного преобразования представлен следующими шагами: [матрица проекции
ProjectionMatrix
] × [матрица просмотра ViewMatrix
] × [матрица модели ModelMatrix
] × координаты вершины. Здесь матрицы проекции и просмотра могут быть абстрагированы как свойства камеры в трёхмерной сцене.
ModelMatrix
× координаты вершины (внутри модели) = координаты вершины в мировых координатах (абсолютные координаты)ViewMatrix
× координаты мировых координат = координаты вершины относительно камеры (координаты относительно камеры)ProjectionMatrix
× координаты вершины относительно камеры = координаты вершины на двумерном экранеОсновное отличие WebVR-приложений от обычных сцен WebGL заключается в том, что:
На основе вышеописанных различий я составил простой процесс разработки приложения WebVR, как показано ниже.
Разработка виртуальной реальности сводится к следующим шагам: инициализация данных VR -> инициализация WebGL -> анимационное отображение.
Используйте метод navigator.getVRDisplays()
для получения экземпляра VR, который возвращает объект Promise. Получите текущий список используемых VR-экземпляров с помощью .then(function(displays){})
.```javascript
let vrDisplay;
navigator.getVRDisplays().then(displays => {
if (displays.length > 0) {
vrDisplay = displays[0];
console.log('Display найдена', vrDisplay);
drawVRScene();
} else {
console.log('Display не найдена');
// Отображение в режиме без VR
// drawScene();
}
});
##### Два. Инициализация WebGL
Обычно инициализация программы WebGL состоит из нескольких этапов: компиляция вершинных и фрагментных шейдеров -> создание буферов вершин и текстур -> установка цвета очистки канвы -> активация тестирования глубины.
```javascript
function drawVRScene() {
const canvas = document.getElementById('glcanvas');
// Получаем контекст WebGL
const gl = canvas.getContext('webgl');
// Инициализация WebGL
init(gl);
// Отображение WebGL
render(gl);
}
function init(gl) {
// Предварительная компиляция шейдеров
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('Не удалось инициализировать шейдеры.');
return;
}
// Создание буфера вершин
initVertexBuffers(gl);
// Создание буфера текстур
initTextures(gl, './assets/texture.jpg');
gl.clearColor(0.4, 0.4, 0.4, 1.0);
// Активация тестирования глубины
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
}
Цель вершинного шейдера — выполнить вычисление координат вершины, матриц модели-вью-проекции и передать их в каждый вершинный элемент.```javascript
const VSHADER_SOURCE = attribute vec4 a_Position; uniform mat4 u_MvpMatrix; attribute vec2 a_TexCoord; varying highp vec2 v_TexCoord; void main() { gl_Position = u_MvpMatrix * a_Position; v_TexCoord = a_TexCoord; }
;
Основная задача фрагментного шейдера — обработка цвета пикселей. В данном случае он просто передает координаты текстуры и объект текстуры в фрагментный шейдер.```javascript
const FSHADER_SOURCE = `
uniform sampler2D u_Sampler;
varying highp vec2 v_TexCoord;
void main() {
gl_FragColor = texture2D(u_Sampler, v_TexCoord);
}
`;
После ранней инициализации VR нам нужно создать анимацию для отображения VR-сцены.
requestAnimationFrame
для создания анимацииИспользуйте метод requestAnimationFrame(callback)
экземпляра vrDisplay для рекурсивного выполнения callback-функции.
Этот метод представляет собой специализированную реализацию window.requestAnimationFrame
, которая предпочитает использовать нативную частоту сброса VR-устройства вместо частоты сброса браузера, чтобы обеспечить правильную частоту обновления отрисовки.
функция render(gl, vrDisplay) {
// Создаем объект данных кадра VR
const frameData = new VRFrameData();
const u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');
function animate() {
// TODO
draw(frameData, u_MvpMatrix);
// Через рекурсивный вызов анимационной функции создается анимация
vrDisplay.requestAnimationFrame(animate);
}
animate();
}
Мы используем метод new VRFrameData()
перед запуском анимационного цикла. Объект VRFrameData
представляет собой упакованные данные кадра от WebVR и является ключевым компонентом для виртуальной реальности.
Контекст WebGL предоставляет функцию viewport
, которая позволяет указывать положение и размеры области рендера 3D сцены на холсте.
По умолчанию, область рендера WebGL имеет значение gl.viewport(0, 0, canvas.width, canvas.height)
.
Первые два параметра представляют начальные координаты рендера, а последние два — размеры рендера. Установка левой и правой областей рендера последовательно обеспечивает разделение экрана.```javascript
function draw(frameData, u_MvpMatrix) {
gl.viewport(0, 0, canvas.width * 0.5, canvas.height); // Устанавливаем левое видовое окно
// TODO
gl.viewport(canvas.width * 0.5, 0, canvas.width * 0.5, canvas.height); // Устанавливаем правое видовое окно
// TODO
}
Ширина левого и правого видовых окон составляет половину ширины холста (`canvas`). Начальная точка левого окна находится в `(0,0)`, а начальная точка правого окна — в `(canvas.width * 0.5, 0)`.
##### 2.2 Динамическое рендериование с использованием [VRFrameData](https://developer.mozilla.org/en-US/docs/Web/API/VRFrameData)
Как было упомянуто ранее, для рендера VR требуется динамически рисовать каждую сцену в зависимости от действий пользователя. Это достигается следующими шагами:
1. Получение текущего кадра матрицы проекции и матрицы просмотра через экземпляр `VRFrameData` API WebVR;
2. Передача матриц просмотра-проекции в шейдер для рендера;
3. Генерация следующих данных кадра и отправка их текущему холсту;
4. Переход к следующему кадровому обратному вызову.
Конкретный код представлен ниже:
```javascript
function draw(gl, frameData, u_MvpMatrix) {
const {
leftProjectionMatrix,
leftViewMatrix,
rightProjectionMatrix,
rightViewMatrix
} = frameData;
``````markdown
// Инициализируем модельную матрицу, матрицу модели-просмотра-проекции
let modelMatrix = mat4.create(),
vpMatrix = mat4.create(),
mvpMatrix = mat4.create();
}
// Отображаем левый глаз в левой части холста
gl.viewport(0, 0, canvas.width * 0.5, canvas.height);
// mvpMatrix = ProjectionMatrix × ViewMatrix × ModelMatrix
// Здесь используется mat4 объект из библиотеки gl-matrix.js для выполнения операций с матрицами над float32Array
mat4.multiply(vpMatrix, leftProjectionMatrix, leftViewMatrix);
mat4.multiply(mvpMatrix, vpMatrix, modelMatrix);
// Передаем модель-проекционную матрицу mvpMatrix в шейдер
gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix);
// Отрисовываем левую часть
gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_SHORT, 0);
``````md
// Отображаем правый глаз в правой части холста
gl.viewport(canvas.width * 0.5, 0, canvas.width * 0.5, canvas.height);
mat4.multiply(vpMatrix, rightProjectionMatrix, rightViewMatrix);
mat4.multiply(mvpMatrix, vpMatrix, modelMatrix);
gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix);
gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_SHORT, 0);
// Генерируем данные следующего кадра и заменяем текущие frameData
vrDisplay.getFrameData(frameData);
vrDisplay.submitFrame();
}
Первоначально, перед отрисовкой анимации, мы получаем экземпляр `frameData`, используя `new VRFrameData()`, и передаем его в функцию отрисовки анимации.
Затем, внутри функции анимации, мы получаем свойства экземпляра `frameData`:
| Свойство экземпляра VRFrameData |
| :------------------------------ |
| leftProjectionMatrix | Левая проекционная матрица |
| leftViewMatrix | Левая матрица просмотра |
| rightProjectionMatrix | Правая проекционная матрица |
| rightViewMatrix | Правая матрица просмотра |
Конечно, `VRFrameData` также включает такие свойства как `pose` и `orientation`, но они здесь не указаны.
С использованием этих формул вычисляем модели-матрицы просмотра и проекции для левого и правого глаза и передаем их в вершинный шейдер, где они перемножаются с координатами вершин из буфера вершин для получения окончательной позиции вершин.
> MvpMatrix = ProjectionMatrix × ViewMatrix × ModelMatrix
```Наконец, перед завершением каждого кадра анимации, мы вызываем `vrDisplay.getFrameData(frameData)`, чтобы сгенерировать данные следующего кадра и заменить текущие `frameData`. Затем используем `vrDisplay.submitFrame()` для отправки текущего кадра на отрисовку на текущий холст.На этом основные этапы разработки приложения WebVR закончены. Для более подробного понимания можно обратиться к примеру ниже.

Проектный код: [https://github.com/YoneChen/webvr-demo](https://github.com/YoneChen/webvr-demo)
### Заключение
Разработка приложений WebVR с использованием нативного WebGL значительно сложнее, чем использование three.js или A-Frame, но именно такой подход позволяет более глубоко понять принципы работы WebVR.
Для изучения разработки WebVR с помощью three.js можно обратиться к статье ["ВР-волна приходит — что могут сделать веб-разработчики?"](https://zhuanlan.zhihu.com/p/25567905). Также приветствую подписку на мой цикл статей [«Усадьба технологий WebVR»](https://zhuanlan.zhihu.com/c_99472965), где материалы будут регулярно обновляться.
### Ссылки на дополнительные материалы
- Основы компьютерной графики: [Матричные преобразования](http://www.opengl-tutorial.org/cn/beginners-tutorials/tutorial-3-matrices/)
- Быстрый старт с WebGL: [Руководство по подготовке к работе с WebGL](http://taobaofed.org/blog/2015/12/21/webgl-handbook/)
- Google Developers | WebVR: [Основы WebVR](https://developers.google.com/web/fundamentals/vr/)
- MDN | WebVR API: [Использование WebVR API](https://developer.mozilla.org/en-US/docs/Web/API/WebVR_API/Using_the_WebVR_API)
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )