WebVR Часть 5: Дизайн и реализация

Опубликовано: 2022-03-11

Я люблю доводить проекты до «готовости». Мы подошли к концу нашего пути — к рождению нашей симуляции небесной гравитации в WebVR.

В этом заключительном посте мы подключим наш высокопроизводительный код моделирования (статьи 1, 2, 3) к визуализатору WebVR на основе визуализатора холста (статья 4).

  1. «Проблема n-тела» Введение и Архитектура
  2. Web Workers дают нам дополнительные потоки браузера
  3. WebAssembly и AssemblyScript для кода узкого места производительности O(n²)
  4. Визуализация данных холста
  5. Визуализация данных WebVR

Это более длинная статья, поэтому мы пропустим некоторые технические детали, рассмотренные ранее. Проверьте предыдущие сообщения, если вы хотите ориентироваться, или читайте опасно.

Мы изучали смену парадигмы браузера от однопоточной среды выполнения JavaScript к многопоточной (веб-работники) высокопроизводительной среде выполнения (WebAssembly). Эти функции высокопроизводительных настольных вычислений доступны в прогрессивных веб-приложениях и модели распространения SaaS.

Демонстрация веб-VR
Демонстрация WebVR, пример кода

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

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

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

Вы не VR-дизайнер, если не можете схватиться. Это смелое заявление, и сегодня мы поговорим о дизайне виртуальной реальности. Это поле изобретается, когда вы читаете это. Моя цель — поделиться своим опытом работы с программным обеспечением и фильмами, чтобы начать разговор о «в первую очередь VR-дизайне». Мы все учимся друг у друга.

Имея в виду эти грандиозные прогнозы, я хотел завершить этот проект как профессиональную техническую демонстрацию — WebVR — отличный выбор для этого!

WebVR и Google A-Frame

Git-репозиторий WebVR является форком версии Canvas по нескольким причинам. Это упрощает размещение проекта на страницах Github, а для WebVR потребовалось несколько изменений, которые загромождали бы версию холста и эти статьи.

Если вы помните наш первый пост об архитектуре, мы делегировали всю симуляцию nBodySimulator .

`nBodySimulator`

Сообщение веб-работника показало, что nBodySimulator имеет функцию step() , вызываемую каждые 33 мс симуляции. step() вызывает calculateForces() для запуска нашего кода моделирования WebAssembly O(n²) (статья 3), затем обновляет позиции и перерисовывает. В нашем предыдущем посте о создании визуализации холста мы реализовали это с помощью элемента холста, начиная с этого базового класса:

 /** * Base class that console.log()s the simulation state. */ export class nBodyVisualizer { constructor(htmlElement) { this.htmlElement = htmlElement this.resize() this.scaleSize = 25 // divided into bodies drawSize. drawSize is log10(mass) // This could be refactored to the child class. // Art is never finished. It must be abandoned. } resize() {} paint(bodies) { console.log(JSON.stringify(bodies, null, 2)) } }

Определите проблему интеграции

У нас есть симуляция. Теперь мы хотим интегрироваться с WebVR — без перестройки нашего проекта. Какие бы корректировки мы ни вносили в симуляцию, они происходят каждые 33 мс в основном потоке пользовательского интерфейса в функции paint(bodies) .

Вот как мы будем измерять «сделано». Я взволнован - давайте приступим к работе!

Как создать виртуальную реальность

Во-первых, нам нужен дизайн:

  • Из чего состоит ВР?
  • Как выражается дизайн WebVR ?
  • Как мы можем с ним взаимодействовать ?

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

Мы можем в 10 раз увеличить нашу историю у костра, добавив 3D-стереоскопические визуальные эффекты и звук. Мой инструктор по бюджетированию кинопроизводства говорил: «Мы платим только за постер. Мы не строим реальность».

Если вы знакомы с DOM браузера, то знаете, что он создает древовидную иерархическую структуру.

График плоской веб-сцены
Плоский «граф сцены».

В дизайне сети подразумевается, что зритель смотрит «спереди». Глядя сбоку, мы увидим элементы DOM в виде линий, а сзади мы увидим только <body> , потому что он скрывает дочерние элементы.

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

Обратите внимание, что болезнь виртуальной реальности — это не шутки. И наши глаза, и внутреннее ухо обнаруживают движение. Это очень важно для животного, которое ходит прямо. Когда эти датчики движения расходятся во мнениях, наш мозг естественным образом предполагает, что наш рот снова ел какую-то чепуху, и его рвет. Все мы когда-то были детьми. Об этом инстинкте выживания в виртуальной реальности уже много написано. Игра «Epic Fun» бесплатна в Steam, а американские горки — лучшая демо-версия VR-болезни, которую я нашел.

Виртуальная реальность выражается как «граф сцены». Граф сцены имеет тот же древовидный шаблон, что и DOM, чтобы скрыть детали и сложность убедительной трехмерной среды. Однако вместо прокрутки и маршрутизации мы позиционируем зрителя там, где он хочет привлечь внимание к себе.

Вот график сцены Hello World из Google A-Frame WebVR Framework:

 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello, WebVR! • A-Frame</title> <meta name="description" content="Hello, WebVR! • A-Frame"> <script src="https://aframe.io/releases/0.9.2/aframe.min.js"></script> </head> <body> <a-scene background="color: #FAFAFA"> <a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9" shadow></a-box> <a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E" shadow></a-sphere> <a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D" shadow></a-cylinder> <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4" shadow></a-plane> </a-scene> </body> </html>

Этот HTML-документ создает DOM в браузере. Теги <a-*> являются частью структуры A-Frame, а <a-scene> является корнем графа сцены. Здесь мы видим четыре 3D-примитива, отображаемых в сцене.

Сцена A-Frame в плоском веб-браузере
Сцена A-Frame в плоском веб-браузере.

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

Сцена A-Frame в виртуальной реальности
Сцена A-Frame в виртуальной реальности — по одному изображению для каждого глаза.

Теоретически вы должны уметь:

  1. Откройте это на своем телефоне
  2. Поднесите телефон к лицу
  3. Наслаждайтесь великолепием новой реальности!

У меня никогда не получалось, чтобы это работало без причудливых линз гарнитуры VR. Вы можете недорого приобрести гарнитуру VR для телефона Android (базовое устройство на базе Google Cardboard), однако для разработки контента я предлагаю автономный HMD (головной дисплей), такой как Oculus Quest.

Подобно подводному плаванию с аквалангом или прыжкам с парашютом, виртуальная реальность — это спорт со снаряжением.

Обучение VR-дизайнеров «Утёс»

Реальность с гравитацией и светом
Добро пожаловать в эту комфортную реальность с гравитацией и светом.

Обратите внимание, что сцена Hello World A-Frame имеет освещение и камеру по умолчанию:

  • Грани куба разного цвета - куб самозатеняющийся.
  • Куб отбрасывает тень на плоскость - есть направленный свет.
  • Между кубом и плоскостью нет промежутка — это мир с гравитацией.

Это критические сигналы, которые говорят зрителю: «Расслабься, эта вещь на твоем лице совершенно нормальна».

Также обратите внимание, что эта настройка по умолчанию неявно присутствует в приведенном выше коде сцены Hello World. A-Frame мудро обеспечивает разумное значение по умолчанию, но имейте в виду: камера и освещение — это пропасть, которую дизайнеры плоского веба должны преодолеть, чтобы создать виртуальную реальность.

Мы принимаем настройку освещения по умолчанию как должное. Например, кнопки:

Кнопки

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

Проектирование, общение и реализация настроек освещения и камеры — это утес для обучения дизайнера WebVR. «Язык кино» — это набор культурных норм, выраженных в различных установках камеры и освещения, которые эмоционально передают историю зрителям. Профессионалы в кино, которые проектируют/перемещают свет и камеру вокруг сцены, являются отделом захвата.

Вернемся к нашей виртуальной реальности

Итак, давайте вернемся к работе. Наша небесная сцена WebVR имеет похожий паттерн:

 <!DOCTYPE> <html> <head> <script src="https://aframe.io/releases/0.9.2/aframe.min.js"></script> <script src="https://unpkg.com/[email protected]/dist/aframe-event-set-component.min.js"></script> <script src="main.js"></script> </head> <body> <a-scene> <a-sky color="#222"></a-sky> <a-entity geometry="primitive: circle; radius: 12" position="0 0 -.5" material="color: #333; transparent: true; opacity: 0.5"> <a-sphere color="black" radius=."02"></a-sphere> </a-entity> <a-entity></a-entity> <a-entity geometry="primitive: plane; width: 2; height: auto" position="0 -10 .3" rotation="55 0 0" material="color: blue" text="value: Welcome Astronaut!..."> </a-entity> <a-entity position="0 -12 .7" rotation="55 0 0"> <a-camera> <a-cursor color="#4CC3D9" fuse="true" timeout="1"></a-cursor> </a-camera> </a-entity> </a-scene> </body> </html>

Этот HTML-документ загружает структуру A-Frame и подключаемый модуль взаимодействия. Наша сцена начинается с <a-scene> .

Внутри мы начинаем с элемента <a-sky color="#222"></a-sky> для цвета фона всего, что мы не определяем в сцене.

Затем мы создаем «орбитальную плоскость», за которую зритель может «держаться», пролетая над нашим странным и неизведанным миром. Мы создаем это как диск и маленькую черную сферу в (0,0,0). Без этого поворот казался мне «необоснованным»:

 <a-entity geometry="primitive: circle; radius: 12" position="0 0 -.5" material="color: #333; transparent: true; opacity: 0.5"> <a-sphere color="black" radius=."02"></a-sphere> </a-entity>

Затем мы определяем коллекцию, в которую мы можем добавлять/удалять/перемещать объекты A-Frame.

 <a-entity></a-entity>

Это расчистка для paint(bodies) nBodyVisualizer для выполнения своей работы.

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

 <a-entity geometry="primitive: plane; width: 2; height: auto" position="0 -10 .3" rotation="55 0 0" material="color: blue" text="value: Welcome Astronaut!\n ..."> </a-entity>

Это завершает наш граф сцены. Наконец, мне нужно было какое -то взаимодействие на демо-версии телефона между пользователем и этим вращающимся миром. Как мы можем воссоздать кнопку «Выбросить мусор» в VR?

Кнопка — это основной элемент любого современного дизайна. Где кнопки виртуальной реальности?

Взаимодействие в WebVR

Виртуальная реальность имеет свои «сверху» и «снизу». Первое взаимодействие зрителя происходит через его аватар или камеру. Это все элементы управления для масштабирования.

Если вы читаете это на компьютере, вы можете использовать WASD для перемещения и мышь для поворота камеры. Это исследование раскрывает информацию, но не выражает вашу волю.

Real Reality имеет несколько очень важных функций, которые редко можно найти в Интернете:

  • Перспектива — объекты становятся заметно меньше по мере удаления от нас.
  • Окклюзия - объекты скрываются и открываются в зависимости от положения.

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

В WebVR мы взаимодействуем в 3D-пространстве. Для этого у нас есть два основных инструмента:

  • Столкновение — пассивное 3D-событие, возникающее, когда два объекта находятся в одном пространстве.
  • Проекция — вызов активной 2D-функции, в которой перечислены все объекты, пересекающие линию.

Столкновение — самое «виртуальное» взаимодействие

В VR «столкновение» звучит именно так: когда два объекта находятся в одном пространстве, A-Frame создает событие.

Чтобы пользователь «нажал» на кнопку, мы должны дать ему пешку и что-то, чем можно нажать на кнопку.

К сожалению, WebVR пока не может использовать контроллеры — многие люди будут смотреть плоскую веб-версию на своем настольном компьютере или телефоне, а многие будут использовать гарнитуру, такую ​​как Google Cardboard или Samsung Gear VR, для демонстрации стереоскопической версии.

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

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

Проекция — это 2D «веб-подобный» щелчок в 3D-пространстве

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

Луч телепорта прослеживает линию в мире, чтобы показать, куда игрок может двигаться. Эта «проекция» ищет места для посадки. Он возвращает один или несколько объектов на пути проекции. Вот пример телепортирующегося луча:

Луч телепортации в стандартном контенте Unreal Engine
Луч телепортации в контенте Unreal Engine по умолчанию.

Обратите внимание, что на самом деле луч реализован как парабола, направленная вниз. Это означает, что он естественным образом пересекается с «землей», как брошенный предмет. Это также естественным образом устанавливает максимальное расстояние телепортации. Ограничения — самый важный выбор дизайна в виртуальной реальности. К счастью, реальность имеет много естественных ограничений.

Проекция «сглаживает» 3D-мир в 2D, поэтому вы можете указать на объект и щелкнуть по нему, как мышью. Шутеры от первого лица — это тщательно продуманные игры с «двухмерным кликом» по вызывающе раздражающим кнопкам — часто с тщательно продуманной историей, объясняющей, почему эти чертовы кнопки «нажимают» на вас не в порядке.

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

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

Проекция без контроллеров с помощью «Взгляда»

Чтобы создать этот примитив взаимодействия в WebVR без контроллеров, мы можем проецировать «взгляд» зрителей как «курсор» линии обзора. Этот курсор можно использовать программно для взаимодействия с объектами с помощью «предохранителя». Это сообщается зрителю в виде маленького синего круга. Теперь мы щелкаем!

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

В A-Frame мы выражаем камеру (невидимую пешку игроков) и этот «курсор» линии обзора как оснастку нашей камеры. Размещение <a-cursor> внутри <a-camera> приводит к тому, что преобразования камеры также применяются к курсору. Когда игрок перемещает/вращает свою фишку ( a-camera ), он также перемещает/вращает его взгляд ( a-cursor ).

 // src/index.html <a-entity position="0 -12 .7" rotation="55 0 0"> <a-camera> <a-cursor color="#4CC3D9" fuse="true" timeout="1"></a-cursor> </a-camera> </a-entity>

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

Я использовал освещение по умолчанию, так что вы можете заметить неосвещенную «обратную сторону» солнца. Хотя я не был за пределами орбитальной плоскости, я не думаю, что Солнце работает именно так. Тем не менее, это работает для нашего технического демонстрационного плаката реальности.

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

У нас есть план интеграции

Теперь у нас есть точки интеграции между A-Frame <a-scene> и нашей симуляцией JavaScript:

A-кадр <a-scene> :

  • Именованная коллекция для тел: <a-entity></a-entity>

  • Курсор, который будет генерировать события проекции: <a-cursor color="#4CC3D9" fuse="true" timeout="1"></a-cursor>

Наша симуляция JavaScript:

  • nBodyVisWebVR.paint(bodies) - добавить/удалить/переместить объекты виртуальной реальности из тел моделирования

  • addBodyArgs(name, color, x, y, z, mass, vX, vY, vZ) чтобы добавить в симуляцию новые тела обломков.

index.html загружает main.js , который инициализирует нашу симуляцию так же, как и версию Canvas:

 // src/main.js import { nBodyVisualizer, nBodyVisWebVR } from ."/nBodyVisualizer" import { Body, nBodySimulator } from ."/nBodySimulator" window.onload = function() { // Create a Simulation const sim = new nBodySimulator() // this Visualizer manages the UI sim.addVisualization(new nBodyVisWebVR(document.getElementById("a-bodies"), sim)) // making up stable universes is hard // name color xyzm vz vy vz sim.addBody(new Body("star", "yellow", 0, 0, 1, 1e9)) sim.addBody(new Body("hot-jupiter", "red", -1, -1, 1, 1e4, .24, -0.05, 0)) sim.addBody(new Body("cold-jupiter", "purple", 4, 4, .5, 1e4, -.07, 0.04, 0)) // Start simulation sim.start() // Add another sim.addBody(new Body("saturn", "blue", -8, -8, .1, 1e3, .07, -.035, 0)) }

Вы заметите, что здесь мы установили htmlElement визуализатора в коллекцию a-bodies body для хранения тел.

Программное управление объектами A-Frame из JavaScript

Объявив нашу сцену в index.html , теперь мы готовы написать код визуализатора.

Во-первых, мы настраиваем nBodyVisualizer для чтения из списка тел nBodySimulation и создания/обновления/удаления объектов A-Frame в коллекции <a-entity></a-entity> .

 // src/nBodyVisualizer.js /** * This is the WebVR visualizer. * It's responsible for painting and setting up the entire scene. */ export class nBodyVisWebVR extends nBodyVisualizer { constructor(htmlElement, sim) { // HTML Element is a-collection#a-bodies. super(htmlElement) // We add these to the global namespace because // this isn't the core problem we are trying to solve. window.sim = sim this.nextId = 0 } resize() {}

В конструкторе мы сохраняем нашу коллекцию A-Frame, устанавливаем глобальную переменную для нашего события «взгляд», чтобы найти симуляцию, и инициализируем счетчик идентификаторов, который мы будем использовать для сопоставления тел между нашей симуляцией и сценой A-Frame.

 paint(bodies) { let i // Create lookup table: lookup[body.aframeId] = body const lookup = bodies.reduce( (total, body) => { // If new body, give it an aframeId if (!body.aframeId) body.aframeId = `a-sim-body-${body.name}-${this.nextId++}` total[body.aframeId] = body return total }, {}) // Loop through existing a-sim-bodies and remove any that are not in // the lookup - this is our dropped debris const aSimBodies = document.querySelectorAll(."a-sim-body") for (i = 0; i < aSimBodies.length; i++) { if (!lookup[aSimBodies[i].id]) { // if we don't find the scene's a-body in the lookup table of Body()s, // remove the a-body from the scene aSimBodies[i].parentNode.removeChild(aSimBodies[i]); } } // loop through sim bodies and upsert let aBody bodies.forEach( body => { // Find the html element for this aframeId aBody = document.getElementById(body.aframeId) // If html element not found, make one. if (!aBody) { this.htmlElement.innerHTML += ` <a-sphere class="a-sim-body" dynamic-body ${ (body.name === "star") ? "debris-listener event-set__enter='_event: mouseenter; color: green' event-set__leave='_event: mouseleave; color: yellow'" : ""} position="0 0 0" radius="${body.drawSize/this.scaleSize}" color="${body.color}"> </a-sphere>` aBody = document.getElementById(body.aframeId) } // reposition aBody.object3D.position.set(body.x, body.y, body.z) }) }

Во-первых, мы перебираем тела симуляции, чтобы пометить и/или создать таблицу поиска для сопоставления объектов A-Frame с телами симуляции.

Затем мы перебираем существующие тела A-Frame и удаляем все, что было обрезано симуляцией для выхода за границы. Это увеличивает воспринимаемую эффективность опыта.

Наконец, мы перебираем тела симов, чтобы создать новую <a-sphere> для отсутствующих тел и изменить положение остальных с помощью aBody.object3D.position.set(body.x, body.y, body.z)

Мы можем программно изменять элементы в сцене A-Frame, используя стандартные функции DOM. Чтобы добавить элемент на сцену, мы добавляем строку в файл innerHTML контейнера. Этот код кажется мне странным, но он работает, и я не нашел ничего лучше.

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

 <a-sphere class="a-sim-body" dynamic-body ${ (body.name === "star") ? "debris-listener event-set__enter='_event: mouseenter; color: green' event-set__leave='_event: mouseleave; color: yellow'" : ""} position="0 0 0" radius="${body.drawSize/this.scaleSize}" color="${body.color}"> </a-sphere>`

Если тело представляет собой «звезду», мы добавляем дополнительные атрибуты, описывающие его события. Вот как выглядит наша звезда при монтировании в DOM:

 <a-sphere class="a-sim-body" dynamic-body="" debris-listener="" event-set__enter="_event: mouseenter; color: green" event-set__leave="_event: mouseleave; color: yellow" position="0 0 0" radius="0.36" color="yellow" material="" geometry=""></a-sphere>

Три атрибута, debris-listener , event-set__enter и event-set__leave , настраивают наши взаимодействия и являются последним этапом нашей интеграции.

Определение событий и взаимодействий A-Frame

Мы используем пакет NPM «aframe-event-set-component» в атрибутах объекта, чтобы изменить цвет солнца, когда зритель «смотрит» на него.

Этот «взгляд» является проекцией положения и поворота зрителя, и взаимодействие обеспечивает необходимую обратную связь о том, что его взгляд что-то делает.

Наша звездная сфера теперь имеет два сокращенных события, включенных плагином, event-set__enter и event-set__leave :

 <a-sphere ... event-set__enter="_event: mouseenter; color: green" event-set__leave="_event: mouseleave; color: yellow" … ></a-sphere>

Затем мы украшаем нашу звездную сферу debris-listener который мы реализуем как пользовательский компонент A-Frame.

 <a-sphere ... debris-listener="" … ></a-sphere>

Компоненты A-Frame определены на глобальном уровне:

 // src/nBodyVisualizer.js // Component to add new bodies when the user stares at the sun. See HTML AFRAME.registerComponent('debris-listener', { init: function () { // Helper function function rando(scale) { return (Math.random()-.5) * scale } // Add 10 new bodies this.el.addEventListener('click', function (evt) { for (let x=0; x<10; x++) { // name, color, x, y, z, mass, vx, vy, vz window.sim.addBodyArgs("debris", "white", rando(10), rando(10), rando(10), 1, rando(.1), rando(.1), rando(.1)) } }) } })

Этот компонент A-Frame действует как прослушиватель «щелчка», который может быть запущен курсором взгляда, чтобы добавить 10 новых случайных тел в нашу сцену.

Обобщить:

  1. Мы объявляем сцену WebVR с A-Frame в стандартном HTML.
  2. Мы можем программно добавлять/удалять/обновлять объекты A-Frame в сцене из JavaScript.
  3. Мы можем создавать взаимодействия в JavaScript с обработчиками событий через плагины и компоненты A-Frame.

WebVR: Вени, Види, Вичи

Надеюсь, вы получили от этой технической демонстрации столько же пользы, сколько и я. Там, где мы применили эти функции (веб-воркеры и WebAssembly) к WebVR, их также можно применить к вычислениям на границе браузера.

Пришла огромная технологическая волна - Виртуальная реальность (VR). Что бы вы ни чувствовали, когда впервые брали в руки смартфон, первое знакомство с виртуальной реальностью дает 10-кратный эмоциональный опыт во всех аспектах работы с компьютером. Прошло всего 12 лет с момента появления первого iPhone.

Виртуальная реальность существует намного дольше, но технология, необходимая для того, чтобы донести виртуальную реальность до обычных пользователей, появилась благодаря мобильной революции и Oculus Quest от Facebook, а не революции ПК.

Интернет и открытый исходный код являются одними из величайших чудес света человечества. За всех людей, создавших плоский интернет, я поднимаю тост за ваше мужество и стремление к приключениям.

Манифест! Мы будем строить миры, потому что у нас есть сила творить.

Демонстрация веб-VR
Демо Canvas, демо WebVR, пример кода