Дополненная реальность (AR) приносит цифровую информацию или мультимедиа и переплетает их с нашим опытом реального мира. В последние годы дополненная реальность стала очевидной в потребительском пространстве в двух основных форматах: наголовные дисплеи, такие как Microsoft HoloLens и Magic Leap, а также более широко доступные возможности на мобильных устройствах. Здесь приложения обычно захватывают камеру устройства, а затем накладывают цифровые артефакты на окно просмотра устройства. Некоторыми примерами популярных мобильных приложений дополненной реальности являются Pokemon Go и Snapchat Lens. Оба предоставляют пользователям приложения, которые позволяют объединить цифровой мир с реальным миром.

Нативные мобильные приложения начали добиваться определенного успеха в области дополненной реальности, но поддержка в Интернете получила менее широкое распространение. Традиционно Интернет не предоставлял собственных функций дополненной реальности, и работа была сосредоточена на подходах к дополненной реальности на основе маркеров с клиентскими библиотеками. Отслеживание на основе маркеров позволяет ориентировать и размещать объекты путем определения определенных шаблонов (маркеров) в сцене. Многие из известных библиотек JavaScript используют этот подход для достижения AR.

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

Переход к объединению работы в направлении WebVR и WebAR пришел к консенсусу в качестве Группы иммерсивного веб-сообщества, и теперь работа движется к новому API, называемому API устройства WebXR. С помощью этой краткой истории дополненной реальности в Интернете давайте рассмотрим текущее положение дел для разработчиков в 2019 году.

AR на основе маркеров с библиотеками JavaScript

Одна из самых популярных библиотек дополненной реальности — ar.js, набравшая более 12 тысяч звезд на GitHub. Прежде чем углубляться в ar.js, важно больше узнать о его зависимости от ARToolKit, давно зарекомендовавшей себя и популярной собственной кросс-платформенной библиотеки дополненной реальности, написанной на C/C++. Библиотека ar.js содержит порт emscripten, artoolkitjs, который требуется в качестве внешней глобальной зависимости для ar.js и должен быть загружен первым. ARToolKit активно не поддерживается, но форк artoolkitX остается активным. Таким образом, уровень поддержки в настоящее время не является интуитивно понятным или простым, но на сегодняшний день его достаточно, чтобы сделать AR возможным в браузере.

ar.js поддерживает three.js и A-Frame в качестве целей для целей рендеринга дополненной реальности. Three.js — полная библиотека 3D-графики для JavaScript, предоставляющая императивный API для построения 3D-сцен поверх WebGL. A-Frame — это платформа для создания опыта виртуальной реальности, использующая декларативный подход с использованием HTML, пользовательских элементов и модели DOM. Вот пример, который будет искать маркер Hiro (тип маркера по умолчанию):

1  <!DOCTYPE html>
2  <html>
3    <head>
4          <style>
5              body {
6                  margin : 0px;
7                  overflow: hidden;
8              }
9          </style>
10     </head>
11
12   <body>
13 
14     <script src="https://jeromeetienne.github.io/AR.js/aframe/examples/vendor/aframe/build/aframe.min.js"></script>
15     <script src='https://jeromeetienne.github.io/AR.js/aframe/build/aframe-ar.js'></script>
16
17     <script>ARjs.Context.baseURL = 'https://jeromeetienne.github.io/AR.js/three.js/'</script>
18
19     <!-- Create a A-Frame Scene and enable tracking with ar.js -->
20     <a-scene embedded arjs='trackingMethod: best;'>
21
22       <!-- Create an A-Frame anchor for our 3D models, detect for marker -->
23       <a-anchor hit-testing-enabled='true'>
24
25         <!-- Provide a rotating Box and Torus Knot -->
26         <a-box position='0 0.5 0' material='opacity: 0.5; side:double; color:red;'>
27           <a-torus-knot radius='0.26' radius-tubular='0.05'>
28             <a-animation attribute="rotation" to="360 0 0" dur="5000" easing='linear' repeat="indefinite"></a-animation>
29           </a-torus-knot>
30         </a-box>
31 
32        </a-anchor>
33
34        <a-camera-static/>
35
36       </a-scene>
37  </body>
38  </html>

ar.js также предоставляет интерфейс для работы с three.js аналогичным образом. В целом ar.js — отличная библиотека, но в ней есть пара текущих проблем. Например, хотя ar.js находится в npm, он не входит в комплект как модуль и поэтому в настоящее время плохо работает с такими сборщиками модулей, как Webpack или Rollup, поэтому его необходимо поместить в тег скрипта, чтобы использовать его как глобальный.

— это новая созданная мной библиотека, основанная на ar.js и artoolkitjs, чтобы предоставить современную библиотеку, написанную на TypeScript. В THREE AR artoolkit поставляется вместе с требуемыми двоичными данными параметров камеры, которые требуются для artoolkit. Инкапсуляция этих двух элементов означает, что THREE AR не имеет внешних внешних зависимостей, кроме three.js. THREE AR также использует подход, основанный на Promise, вместо обхода обратных вызовов, что позволяет использовать более современные стили кодирования (например, вы можете использовать его с async/await). Вот пример того, как создать базовый экран, используя простой шаблонный маркер, в данном случае Hiro marker (маркер по умолчанию):

1  import * as THREEAR from "threear";
2  import * as THREE from "three";
3 
4  const renderer = new THREE.WebGLRenderer({
5      antialias: true,
6      alpha: true
7  });
8
9  renderer.setClearColor(new THREE.Color('lightgrey'), 0)
10 renderer.setSize( window.innerWidth, window.innerHeight ); 
11 renderer.domElement.style.position = 'absolute'
12 renderer.domElement.style.top = '0px'
13 renderer.domElement.style.left = '0px'
14 document.body.appendChild( renderer.domElement );
15
16 // Initialise the three.js scene and camera
17 const scene = new THREE.Scene();
18 const camera = new THREE.Camera();
19 scene.add(camera);
20
21 const markerGroup = new THREE.Group();
22 scene.add(markerGroup);
23
24 var source = new THREEAR.Source({ renderer, camera });
25 
26 THREEAR.initialize({ source: source }).then((controller) => {
27 
28     // Add a torus knot
29     const geometry = new THREE.TorusKnotGeometry(0.3,0.1,64,16);
30     const material = new THREE.MeshNormalMaterial();
31     const torus = new THREE.Mesh( geometry, material );
32     torus.position.y = 0.5
33     markerGroup.add(torus);
34
35     var patternMarker = new THREEAR.PatternMarker({
36         patternUrl: 'patt.hiro', // the URL of the hiro pattern
37         markerObject: markerGroup,
38         minConfidence: 0.4 // The confidence level before the marker should be shown
39     });
40     
41     controller.trackMarker(patternMarker);
42      
43     // run the rendering loop
44     let lastTimeMilliseconds = 0;
45     requestAnimationFrame(function animate(nowMsec){
46         // keep looping
47         requestAnimationFrame( animate );
48         // measure time
49         lastTimeMilliseconds = lastTimeMilliseconds || nowMsec-1000/60;
50         const deltaMillisconds = Math.min(200, nowMsec - lastTimeMilliseconds);
51         lastTimeMilliseconds = nowMsec;
52 
53         // call each update function
54         controller.update( source.domElement );
55
56         torus.rotation.y += deltaMillisconds/1000 * Math.PI
57         torus.rotation.z += deltaMillisconds/1000 * Math.PI
58         renderer.render( scene, camera );
59    });
60
61  });

Наконец, awe.js — это библиотека от awe-media, которая предлагает функции, аналогичные ar.js. К сожалению, awe.js не обновлялся последние два года. Интересно, что в awe.js также есть пример взаимодействия с ARToolKit, хотя и в другой форме, с использованием JavaScript-порта ActionScript-порта ARToolKit (port-ception!). Еще одна функция, которую поддерживает awe.js, — это маркеры на основе местоположения, использующие датчики устройства для позиционирования объекта. Просмотрите примеры awe.js для получения дополнительной информации.

Взгляд в будущее: WebXR

Будущее нативной дополненной реальности в браузере многообещающее, хотя, возможно, и сложное. В настоящее время основное внимание уделяется текущей работе над спецификацией WebXR, которая заменяет спецификацию API браузера WebVR, выпущенную в 2017 году. Появление ARCore (Android) и ARKit (iOS) послужило стимулом для продвижения AR в Интернете. и поэтому была разработана новая спецификация, чтобы объединить интересы AR и VR.

В конечном счете, спецификация WebXR направлена ​​на то, чтобы обеспечить в браузере как виртуальную реальность, так и дополненную реальность и смешанную реальность. Для API WebXR требуется подходящее оборудование, такое как совместимые с ARCore устройства или Microsoft HoloLens.

На данный момент есть несколько примеров использования WebXR API. Mozilla создала несколько демонстраций, которые работают для iOS ARKit с использованием Mozilla webxr-polyfill. Google делает аналогичную работу, показывая, как можно использовать ARCore и Chrome Canary для использования WebXR API в браузере.

API WebXR все еще находится в стадии разработки, и стандарт все еще дорабатывается. Репозиторий группы WebXR на GitHub содержит обновленную информацию о спецификации WebXR, включая проект спецификации WebXR. Существует по крайней мере два примечательных полифилла для WebXR API, причем официальный полифил Immersive Web Community Group WebXR активно поддерживается и поддерживается.

Давайте посмотрим, как можно использовать API. Образцы кода для примеров являются существенными и сокращены здесь, чтобы предоставить фрагменты основного API JavaScript, чтобы проиллюстрировать, как API WebXR работает для функций дополненной реальности в Интернете. Этот код адаптирован из примера, где пользователь помещает цифровые подсолнухи в сцену камеры.

1  function initXR() {
2 
3    // Code omitted for brevity
4
5    // Detect that the browser has the WebXR API
6    if (navigator.xr) {
7
8      // Check that the Augmented Reality mode is available
9      navigator.xr.supportsSessionMode('immersive-ar').then(() => {
10       // Do something here, for example disable/enable a start button
11     });
12    }
13
14  }
15
16  function onRequestSession() {
17    navigator.xr.requestSession({ mode: 'immersive-ar' })
18        .then((session) => {
19          xrButton.setSession(session);
20          onSessionStarted(session);
21        });
22  }
23 
24  function onSessionStarted(session) {
25
26    // Add event handlers for the end of the session, and a
27    // user selecting something in the scene
28    session.addEventListener('end', onSessionEnded);
29    session.addEventListener('select', onSelect);
30
31    // Code omitted for brevity
32
33    // Get hold of a reference space, bounded, unbounded, and stationary are the types
34    session.requestReferenceSpace({ type: 'stationary', subtype: 'eye-level' }).then((refSpace) => {
35       xrRefSpace = refSpace;
36       session.requestAnimationFrame(onXRFrame);
37    });
38 
39  }
40
41  function onSelect(event) {
42
43      // Fire a hit test
44      let inputPose = event.frame.getInputPose(event.inputSource, xrRefSpace);
45      if (!inputPose) {
46        return;
47      }
48 
49      if (inputPose.targetRay) {
50
51       vec3.set(rayOrigin,
52           inputPose.targetRay.origin.x,
53           inputPose.targetRay.origin.y,
54           inputPose.targetRay.origin.z);
55       vec3.set(rayDirection,
56           inputPose.targetRay.direction.x,
57           inputPose.targetRay.direction.y,
58           inputPose.targetRay.direction.z);
59
60       // Perform a hit test into the real world
61       event.frame.session.requestHitTest(rayOrigin, rayDirection, xrRefSpace).then((results) => {
62        if (results.length) {
63          // Place the object at the given location
64          addARObjectAt(results[0].hitMatrix);
65        }
66      });
67    }
68
69  }
70
71 }

Вы можете найти полный код этого примера в репозитории примеров Immersive Web Community Group, а также видео для этого примера.

Здесь стоит остановиться на некоторых концепциях. Во-первых, reference spaces указывает на тип пространства, которое требуется для опыта. Доступные варианты bounded, unbounded, stationary. bounded относится к опыту, в котором пользователь будет перемещаться, но не за пределы заранее определенной области. Unbounded означает, что нет никаких ограничений на перемещение пользователей в пространстве. Наконец, stationary относится к опыту, когда пользователь сидит или стоит. Репозиторий WebXR API GitHub предоставляет дополнительное руководство по объяснению пространственного отслеживания.

В этом примере тест попадания (session.requestHitTest) запускает луч в сцену реального мира и определяет, в какой объект реального мира мы попали. Это позволяет нам разместить виртуальный объект в месте пересечения этого луча. Опять же, вы можете найти подробное руководство по тестированию хитов в репозитории WebXR Device API на GitHub.

Этот пример дает представление о WebXR API и о том, как выполнять некоторые основные функции, такие как размещение моделей/объектов в реальной сцене.

Вывод

Теперь можно использовать дополненную реальность в веб-приложениях с помощью библиотек на основе маркеров. Будущее дополненной реальности в Интернете развивается вместе с WebXR Device API, и сегодня ее можно использовать с полифиллом для этого API. Важно учитывать, что даже если вы используете полифилл WebXR, вам все равно потребуется оборудование с поддержкой AR (например, ARCore, ARKit). Поэтому важно учитывать, какой опыт вы хотите создать, и доступность оборудования для ваших целевых пользователей. В дальнейшем мы должны увидеть большую формализацию и укрепление API и более широкое внедрение в современные браузеры.

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

Подписывайтесь на SitePen в Twitter, Facebook и LinkedIn.

Первоначально опубликовано на https://www.sitepen.com 21 мая 2019 г.