Добро пожаловать в иммерсивный Интернет

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

Джо Медли
Joe Medley

Иммерсивный Интернет означает опыт виртуального мира, размещенный через браузер. Сюда входят все возможности виртуальной реальности (VR), отображаемые в браузере или в гарнитурах с поддержкой VR, таких как Google Daydream, Oculus Rift, Samsung Gear VR, HTC Vive и гарнитуры смешанной реальности Windows, а также возможности дополненной реальности, разработанные для мобильных устройств с поддержкой AR. устройства.

Хотя мы используем два термина для описания иммерсивного опыта, их следует рассматривать как диапазон от полной реальности до полностью захватывающей виртуальной среды с различными уровнями AR между ними.

Примеры иммерсивного опыта включают в себя:

  • Захватывающие видео 360°
  • Традиционные 2D (или 3D) видеоролики, представленные в захватывающей обстановке.
  • Визуализация данных
  • Домашние покупки
  • Искусство
  • Что-то крутое, о чем еще никто не думал

Как мне туда добраться?

Иммерсивная сеть доступна уже почти год в зачаточной форме. Это было сделано с помощью API WebVR 1.1 , который доступен в пробной версии начиная с Chrome 62. Этот API также поддерживается Firefox и Edge, а также полифилом для Safari.

Но пришло время двигаться дальше.

Исходная пробная версия закончилась 24 июля 2018 г., и на смену спецификации пришли WebXR Device API и новая исходная пробная версия.

Что случилось с WebVR 1.1?

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

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

API устройства WebXR был разработан и назван с учетом этих расширенных вариантов использования и обеспечивает лучший путь вперед. Разработчики WebVR обязались перейти на API устройств WebXR.

Что такое API устройства WebXR?

Как и предыдущая спецификация WebVR, API устройства WebXR является продуктом группы сообщества Immersive Web Community , в которую входят представители Google, Microsoft, Mozilla и других. «X» в XR задуман как своего рода алгебраическая переменная, которая обозначает что-либо в спектре иммерсивного опыта. Он доступен в ранее упомянутой пробной версии Origin , а также через полифилл .

Когда эта статья была первоначально опубликована в период бета-тестирования Chrome 67, были включены только возможности виртуальной реальности. Дополненная реальность появилась в Chrome 69. Прочтите об этом в разделе «Дополненная реальность для Интернета» .

В этом новом API есть нечто большее, чем я могу рассказать в такой статье. Я хочу дать вам достаточно информации, чтобы вы могли разобраться в примерах WebXR . Дополнительную информацию можно найти как в оригинальном пояснении , так и в нашем Руководстве для первых пользователей Immersive Web . Я буду расширять последнее по мере прохождения испытания происхождения. Не стесняйтесь открывать проблемы или отправлять запросы на включение.

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

Я не буду рассказывать о том, как отображать контент AR/VR на экране. API устройства WebXR не предоставляет функции рендеринга изображений. Это зависит от вас. Рисование выполняется с использованием API WebGL. Вы можете сделать это, если вы действительно амбициозны. Тем не менее, мы рекомендуем использовать фреймворк. В иммерсивных веб-примерах используется один, созданный специально для демонстраций, под названием Cottontail . Three.js поддерживает WebXR с мая. Я ничего не слышал об A-Frame.

Запуск и запуск приложения

Основной процесс таков:

  1. Запросите устройство XR.
  2. Если он доступен, запросите сеанс XR. Если вы хотите, чтобы пользователь подключил свой телефон к гарнитуре, это называется сеансом с погружением и для входа требуется жест пользователя.
  3. Используйте сеанс для запуска цикла рендеринга, который обеспечивает 60 кадров изображения в секунду. Нарисуйте соответствующий контент на экране в каждом кадре.
  4. Запускайте цикл рендеринга, пока пользователь не решит выйти.
  5. Завершите сеанс XR.

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

Запросить устройство XR

Здесь вы узнаете стандартный код обнаружения функции. Вы можете обернуть это в функцию, называемую чем-то вроде checkForXR() .

Если вы не используете иммерсивный сеанс, вы можете пропустить рекламу этой функции и получение жестов пользователя и сразу перейти к запросу сеанса. Иммерсивный сеанс требует использования гарнитуры. Сеанс без погружения просто показывает контент на экране устройства. Первое — это то, о чем думает большинство людей, когда речь идет о виртуальной или дополненной реальности. Последнее иногда называют «волшебным окном».

if (navigator.xr) {
    navigator
.xr.requestDevice()
   
.then(xrDevice => {
   
// Advertise the AR/VR functionality to get a user gesture.
   
})
   
.catch(err => {
   
if (err.name === 'NotFoundError') {
       
// No XRDevices available.
        console
.error('No XR devices available:', err);
   
} else {
       
// An error occurred while requesting an XRDevice.
        console
.error('Requesting XR device failed:', err);
   
}
   
})
} else{
    console
.log("This browser does not support the WebXR API.");
}

Запросить сеанс XR

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

xrPresentationContext = htmlCanvasElement.getContext('xrpresent');
let sessionOptions
= {
   
// The immersive option is optional for non-immersive sessions; the value
   
//   defaults to false.
    immersive
: false,
    outputContext
: xrPresentationContext
}
xrDevice
.requestSession(sessionOptions)
.then(xrSession => {
   
// Use a WebGL context as a base layer.
    xrSession
.baseLayer = new XRWebGLLayer(session, gl);
   
// Start the render loop
})

Запустите цикл рендеринга

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

Основной процесс цикла рендеринга таков:

  1. Запросить кадр анимации.
  2. Запрос положения устройства.
  3. Нарисуйте контент в положении устройства в зависимости от его положения.
  4. Выполните работу, необходимую для устройств ввода.
  5. Повторяйте 60 раз в секунду, пока пользователь не решит выйти.

Запросить рамку для презентации

Слово «фрейм» имеет несколько значений в контексте Web XR. Первый — это система отсчета , которая определяет, откуда рассчитывается начало системы координат и что происходит с этим началом при движении устройства. (Остается ли вид неизменным, когда пользователь перемещается, или он смещается, как в реальной жизни?)

Второй тип кадра — это кадр представления , представленный объектом XRFrame . Этот объект содержит информацию, необходимую для рендеринга на устройстве одного кадра сцены AR/VR. Это немного сбивает с толку, поскольку кадр представления извлекается путем вызова requestAnimationFrame() . Это делает его совместимым с window.requestAnimationFrame() .

Прежде чем я дам вам еще что-нибудь для переваривания, я предложу некоторый код. В приведенном ниже примере показано, как запускается и поддерживается цикл рендеринга. Обратите внимание на двойное использование слова «фрейм». Обратите внимание на рекурсивный вызов requestAnimationFrame() . Эта функция будет вызываться 60 раз в секунду.

xrSession.requestFrameOfReference('eye-level')
.then(xrFrameOfRef => {
    xrSession
.requestAnimationFrame(onFrame(time, xrFrame) {
   
// The time argument is for future use and not implemented at this time.
   
// Process the frame.
    xrFrame
.session.requestAnimationFrame(onFrame);
   
}
});

Позы

Прежде чем рисовать что-либо на экране, вам необходимо знать, куда указывает устройство отображения, и вам нужен доступ к экрану. Вообще положение и ориентация вещи в AR/VR называется позой. И зрители, и устройства ввода имеют позу. (Об устройствах ввода я расскажу позже.) Позы как зрителя, так и устройства ввода определяются как матрица 4 на 4, хранящаяся в Float32Array в порядке следования столбцов. Вы получаете позу зрителя, вызывая XRFrame.getDevicePose() для текущего объекта кадра анимации. Всегда проверяйте, вернулась ли к вам поза. Если что-то пошло не так, вы не захотите рисовать на экране.

let pose = xrFrame.getDevicePose(xrFrameOfRef);
if (pose) {
   
// Draw something to the screen.
}

Просмотры

После проверки позы пришло время что-нибудь нарисовать. Объект, который вы рисуете, называется представлением ( XRView ). Здесь тип сеанса становится важным. Представления извлекаются из объекта XRFrame в виде массива. Если вы находитесь в сеансе без погружения, массив имеет одно представление. Если вы находитесь в сеансе погружения, в массиве их два, по одному на каждый глаз.

for (let view of xrFrame.views) {
   
// Draw something to the screen.
}

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

Весь цикл рендеринга

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

xrSession.requestFrameOfReference('eye-level')
.then(xrFrameOfRef => {
    xrSession
.requestAnimationFrame(onFrame(time, xrFrame) {
   
// The time argument is for future use and not implemented at this time.
    let pose
= xrFrame.getDevicePose(xrFrameOfRef);
   
if (pose) {
       
for (let view of xrFrame.views) {
       
// Draw something to the screen.
       
}
   
}
   
// Input device code will go here.
    frame
.session.requestAnimationFrame(onFrame);
   
}
}

Завершить сеанс XR

Сеанс XR может завершиться по нескольким причинам, включая завершение вашим собственным кодом посредством вызова XRSession.end() . Другие причины включают отключение гарнитуры или управление ею другим приложением. Вот почему правильное приложение должно отслеживать конечное событие и, когда оно происходит, отбрасывать объекты сеанса и средства рендеринга. Завершившийся сеанс XR нельзя возобновить.

xrDevice.requestSession(sessionOptions)
.then(xrSession => {
   
// Create a WebGL layer and initialize the render loop.
    xrSession
.addEventListener('end', onSessionEnd);
});

// Restore the page to normal after immersive access has been released.
function onSessionEnd() {
    xrSession
= null;

   
// Ending the session stops executing callbacks passed to the XRSession's
   
// requestAnimationFrame(). To continue rendering, use the window's
   
// requestAnimationFrame() function.
    window
.requestAnimationFrame(onDrawFrame);
}

Как происходит взаимодействие?

Что касается времени жизни приложения, я просто собираюсь дать вам представление о том, как взаимодействовать с объектами в AR или VR.

API устройства WebXR использует подход «укажи и щелкни» для пользовательского ввода. При таком подходе каждый источник ввода имеет определенный луч указателя , указывающий, куда указывает устройство ввода, и события, указывающие, когда что-то было выбрано. Ваше приложение рисует луч указателя и показывает, куда он направлен. Когда пользователь щелкает устройство ввода, запускаются события — в частности, select , selectStart и selectEnd . Ваше приложение определяет, по чему был сделан щелчок, и реагирует соответствующим образом.

Устройство ввода и луч указателя

Для пользователей луч указателя — это всего лишь слабая линия между контроллером и тем, на что они указывают. Но ваше приложение должно это отрисовать. Это означает получение позы устройства ввода и проведение линии от его местоположения до объекта в пространстве AR/VR. Этот процесс выглядит примерно так:

let inputSources = xrSession.getInputSources();
for (let xrInputSource of inputSources) {
    let inputPose
= frame.getInputPose(inputSource, xrFrameOfRef);
   
if (!inputPose) {
   
continue;
   
}
   
if (inputPose.gripMatrix) {
   
// Render a virtual version of the input device
   
//   at the correct position and orientation.
   
}
   
if (inputPose.pointerMatrix) {
   
// Draw a ray from the gripMatrix to the pointerMatrix.
   
}
}

Это урезанная версия примера отслеживания ввода от группы сообщества Immersive Web. Как и в случае с рендерингом кадров, рисование луча указателя и устройства зависит от вас. Как упоминалось ранее, этот код должен выполняться как часть цикла рендеринга.

Выбор предметов в виртуальном пространстве

Просто указывать на вещи в AR/VR довольно бесполезно. Чтобы сделать что-нибудь полезное, пользователям нужна возможность выбирать вещи. API устройства WebXR предоставляет три события для реагирования на действия пользователя: select , selectStart и selectEnd . У них есть особенность, которую я не ожидал: они сообщают вам только о том, что было нажато устройство ввода. Они не сообщают вам, по какому элементу среды был сделан щелчок. Обработчики событий добавляются к объекту XRSession и должны быть добавлены, как только они станут доступны.

xrDevice.requestSession(sessionOptions)
.then(xrSession => {
   
// Create a WebGL layer and initialize the render loop.
    xrSession
.addEventListener('selectstart', onSelectStart);
    xrSession
.addEventListener('selectend', onSelectEnd);
    xrSession
.addEventListener('select', onSelect);
});

Этот код основан на примере выбора ввода , если вам нужен дополнительный контекст.

Чтобы выяснить, по чему щелкнули, вы используете позу. (Вы удивлены? Я так не думал.) Подробности этого зависят от вашего приложения или используемой вами платформы и, следовательно, выходят за рамки этой статьи. Подход Cottontail представлен в примере выбора входных данных.

function onSelect(ev) {
    let inputPose
= ev.frame.getInputPose(ev.inputSource, xrFrameOfRef);
   
if (!inputPose) {
   
return;
   
}
   
if (inputPose.pointerMatrix) {
   
// Figure out what was clicked and respond.
   
}
}

Вывод: смотрим вперед

Как я уже говорил ранее, дополненная реальность ожидается в Chrome 69 (Canary где-то в июне 2018 года). Тем не менее, я советую вам попробовать то, что у нас есть на данный момент. Нам нужна обратная связь, чтобы сделать его лучше. Следите за его прогрессом, просматривая ChromeStatus.com для проверки нажатия WebXR . Вы также можете следить за привязками WebXR , которые улучшат отслеживание поз.