1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/YorkChan-webvr-demo

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
README.md 22 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 11.03.2025 09:18 de76ffe

Недавно был выпущен WebVR API версии 1.1, а проект 2.0 находится в стадии разработки. По моему мнению, внедрение WebVR во все популярные браузеры — вопрос времени. В сегодняшней статье я расскажу подробнее о среде разработки и процессе создания приложений с использованием WebVR.

WebVR и WebVR API

Сначала стоит отметить, что 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.

Две крупнейших мобильных VR-платформы: Daydream и Gear VR### Настройка среды разработки для WebVR Поскольку WebVR-приложения должны работать на устройствах VR, стоимость которых может быть высока, ниже представлено решение для тестирования WebVR-приложений на компьютере.Первым шагом является запуск веб-сервера для статических страниц WebVR. Для этого можно установить расширение Web Server for Chrome, либо использовать Node.js или выложить код на GitHub.

Тестирование на ПК

1. Установите расширение WebVR API Emulation для Chrome

Это расширение позволяет эмулировать взаимодействие пользователя с устройствами VR.

Эмуляция WebVR API для имитации опыта VR

Тестирование на мобильных устройствах

Для приложений уровня Google Cardboard.

1. Установите Chrome Beta

На данный момент поддержка WebVR находится в раннем экспериментальном этапе. Вам потребуется последняя версия Chrome Beta. После установки вам нужно будет включить поддержку WebVR в настройках браузера, открыв chrome://flags#enable-webvr, нажав "Enable" и перезапустив Chrome.

2. Установите Google VR службы

Это VR-сервисы от Google для пользователей Cardboard и Daydream, предоставляющие возможность запуска окон в режиме VR, как показано ниже.

Наконец, вы можете открыть страницу с примерами WebVR в Chrome для проверки правильности установки.

Пример приложения WebVR###### 3. Отладка с помощью инспектора Chrome Чтобы отладить разработанные вами WebVR-страницы через мобильный браузер Chrome, откройте chrome://inspect в Chrome на вашем компьютере. Подробнее можно узнать из руководства удалённой отладки устройств Android.

После завершения конфигурирования среды разработки WebVR мы можем приступить к работе над проектами WebVR.


Разработка WebVR с использованием WebGL

Разработка приложений WebVR основана на технологии WebGL, которая позволяет создавать и выполнять 3D-графику в браузере. Она следует спецификациям OpenGL ES и использует язык GLSL для управления GPU и выполнения вершинных и пиксельных шейдеров. Матричное преобразование 3D-моделиВ сцене WebGL трёхмерные объекты создаются путём применения матриц преобразования, что приводит к формированию двумерного изображения на экране. Процесс матричного преобразования представлен следующими шагами: [матрица проекции ProjectionMatrix] × [матрица просмотра ViewMatrix] × [матрица модели ModelMatrix] × координаты вершины. Здесь матрицы проекции и просмотра могут быть абстрагированы как свойства камеры в трёхмерной сцене.

ModelMatrix × координаты вершины (внутри модели) = координаты вершины в мировых координатах (абсолютные координаты) ViewMatrix × координаты мировых координат = координаты вершины относительно камеры (координаты относительно камеры) ProjectionMatrix × координаты вершины относительно камеры = координаты вершины на двумерном экранеОсновное отличие WebVR-приложений от обычных сцен WebGL заключается в том, что:

  1. Для WebVR требуется двухканальное отображение, которое имитирует видимость левого и правого глаз пользователя. Поэтому каждое кадровое отображение в WebVR требует дополнительного отрисовывания по сравнению с обычными сценами WebGL;

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

  1. Направление, поле зрения и положение камеры в сцене WebVR (DOF) тесно связано с головным дисплеем пользователя (HMD). Другими словами, когда реальный угол обзора пользователя меняется, камера сцены WebVR также должна динамически изменяться.

На основе вышеописанных различий я составил простой процесс разработки приложения WebVR, как показано ниже. Разработка виртуальной реальности сводится к следующим шагам: инициализация данных VR -> инициализация WebGL -> анимационное отображение.

1. Инициализация данных VR

Используйте метод 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);
}  
Программы шейдеров GLSL

Цель вершинного шейдера — выполнить вычисление координат вершины, матриц модели-вью-проекции и передать их в каждый вершинный элемент.```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-сцены.

3. Анимационное отображение

1. Использование 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 и является ключевым компонентом для виртуальной реальности.

2. ВР-рендеринг

2.1 Использование viewport для установки двойного видового окна

Контекст 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 закончены. Для более подробного понимания можно обратиться к примеру ниже.
![](http://upload-images.jianshu.io/upload_images/1939855-2deb638717d350a5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
Проектный код: [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 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/YorkChan-webvr-demo.git
git@api.gitlife.ru:oschina-mirror/YorkChan-webvr-demo.git
oschina-mirror
YorkChan-webvr-demo
YorkChan-webvr-demo
master