В этой кодовой лаборатории рассматривается пример создания веб-приложения AR. Он использует JavaScript для визуализации 3D-моделей, которые выглядят так, как будто они существуют в реальном мире.
Вы используете API устройства WebXR , который сочетает в себе функции AR и виртуальной реальности (VR). Вы сосредотачиваетесь на расширениях AR для API устройства WebXR, чтобы создать простое приложение AR, которое работает в интерактивном Интернете.
AR — это термин, обычно используемый для описания смешения компьютерной графики с реальным миром. В случае AR на базе телефона это означает убедительное размещение компьютерной графики поверх прямой трансляции с камеры. Чтобы этот эффект оставался реалистичным при движении телефона по миру, устройству с поддержкой AR необходимо понимать мир, в котором оно движется, и определять свою позу (положение и ориентацию) в трехмерном пространстве. Это может включать в себя обнаружение поверхностей и оценку освещения окружающей среды.
AR стала широко использоваться в приложениях после выпуска Google ARCore и Apple ARKit , будь то фильтры для селфи или игры на основе AR.
В этой лаборатории кода вы создадите веб-приложение, которое помещает модель в реальный мир с использованием дополненной реальности. Ваше приложение будет:
Эта лаборатория кода ориентирована на API AR. Нерелевантные концепции и блоки кода замалчиваются и предоставляются вам в соответствующем коде репозитория.
Нажмите «Попробовать» на своем устройстве AR, чтобы попробовать первый шаг этой лаборатории кода. Если вы получаете страницу с сообщением «Ваш браузер не поддерживает функции AR», убедитесь, что на вашем устройстве Android установлены Сервисы Google Play для AR.
Папки step-03 и step-04 содержат желаемое конечное состояние третьего и четвертого шагов этой лаборатории кода, а также final результат. Они здесь для справки.
Вы выполняете всю работу по кодированию в work каталоге.
Далее вы увидите это диалоговое окно, которое позволяет вам настроить локальный веб-сервер:
Настройте свое AR-устройство так, чтобы оно имело доступ к тому же порту на вашей рабочей станции, когда вы посещаете на нем localhost:8887.
Проверьте свое соединение:
Вы должны увидеть страницу с кнопкой «Начать дополненную реальность».
Однако если вы видите страницу с ошибкой «Неподдерживаемый браузер» , возможно, ваше устройство несовместимо.
Теперь соединение с вашим веб-сервером должно работать с вашим устройством AR.
При первом запуске приложения AR вы увидите запрос на доступ к камере.
→
Как только все будет готово, вы должны увидеть сцену из кубов, наложенную поверх изображения с камеры. Понимание сцены улучшается по мере того, как камера анализирует большую часть мира, поэтому перемещение может помочь стабилизировать ситуацию.
Важно ! Из соображений безопасности API устройства WebXR может работать только в безопасных средах (HTTPS), за исключением случаев разработки на локальном хосте. Если у вас возникли проблемы с активацией WebXR, убедитесь, что вы используете защищенный документ или URL-адрес локального хоста.
С этого момента все тестирование и проверка (разделы «Проверка» на последующих этапах) требуют перехода по ссылке на вашем AR-устройстве.
На этом этапе вы узнаете, как настроить сеанс WebXR и базовую сцену AR. HTML-страница снабжена стилем CSS и JavaScript для включения базовых функций AR. Это ускоряет процесс настройки, позволяя команде разработчиков сосредоточиться на функциях AR.
Вы встраиваете AR-опыт в традиционную веб-страницу, используя существующие веб-технологии. В этом случае вы используете полноэкранное полотно рендеринга, поэтому HTML-файл не должен быть слишком сложным.
Для запуска функций AR требуется жест пользователя, поэтому существуют некоторые компоненты Material Design для отображения кнопки «Запустить AR» и сообщения браузера о неподдержке.
Файл index.html , который уже находится в вашем work каталоге, должен выглядеть примерно так: Это часть фактического содержимого; не копируйте этот код в свой файл!
Building an augmented reality application with the WebXR Device API Start augmented reality
Отправная точка вашего приложения находится в app.js Этот файл представляет собой шаблон для настройки AR-опыта.
Этот шаблон использует асинхронные функции. Дополнительные сведения об асинхронных функциях см. в разделе Асинхронные функции — создание дружественных обещаний .
Ваш рабочий каталог также уже содержит код приложения ( app.js ).
Прежде чем пользователь сможет работать с AR, проверьте наличие navigator.xr и необходимых функций XR. Объект navigator.xr является точкой входа для API устройства WebXR, поэтому он должен существовать, если устройство совместимо. Также убедитесь, что поддерживается режим сеанса "immersive-ar" .
Если все в порядке, нажатие кнопки «Войти в дополненную реальность» попытается создать сеанс XR. В противном случае вызывается onNoXRDevice() ( shared/utils.js ), который отображает сообщение об отсутствии поддержки AR.
Этот код уже присутствует в app.js , поэтому никаких изменений вносить не нужно.
(async function() < if (navigator.xr && await navigator.xr.isSessionSupported("immersive-ar")) < document.getElementById("enter-ar").addEventListener("click", activateXR) >else < onNoXRDevice(); >>)();
Несмотря на то, что API устройства WebXR может поддерживаться в браузере, запрошенный режим сеанса может не поддерживаться. Например, настольный браузер может реализовать API, но не иметь подключенного оборудования VR или AR для поддержки взаимодействия. Дополнительные сведения о перечислении устройств см. в спецификации WebXR Device API .
Когда вы нажимаете «Войти в дополненную реальность» , код вызывает activateXR() . Это запускает опыт AR.
activateXR = async () => < // Initialize a WebXR session using "immersive-ar". this.xrSession = /* TODO */; // Omitted for brevity >
Точка входа в WebXR — через XRSystem.requestSession() . Используйте режим immersive-ar чтобы визуализированный контент можно было просматривать в реальной среде.
activateXR = async () => < // Initialize a WebXR session using "immersive-ar". this.xrSession = await navigator.xr.requestSession("immersive-ar"); // . >
XRReferenceSpace описывает систему координат, используемую для объектов в виртуальном мире. 'local' режим лучше всего подходит для AR-опыта, поскольку опорное пространство находится рядом со зрителем и стабильно отслеживается.
Инициализируйте this.localReferenceSpace в onSessionStarted() с помощью следующего кода:
this.localReferenceSpace = await this.xrSession.requestReferenceSpace("local");
requestAnimationFrame XRSession позволяет вам подключиться к частоте обновления собственного устройства XR. Стандартные циклы рендеринга веб-страниц рассчитаны на 60 кадров в секунду, тогда как внешние дисплеи VR могут отображать со скоростью 120 кадров в секунду. Неэксклюзивные сеансы AR по-прежнему могут работать только со скоростью 60 кадров в секунду, но информация о позе и представлении устройства доступна только в requestAnimationFrame сеанса.
В каждом кадре onXRFrame вызывается с меткой времени и XRFrame .
// Queue up the next draw request. this.xrSession.requestAnimationFrame(this.onXRFrame);
// Bind the graphics framebuffer to the baseLayer's framebuffer. const framebuffer = this.xrSession.renderState.baseLayer.framebuffer; this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebuffer); this.renderer.setFramebuffer(framebuffer);
// Retrieve the pose of the device. // XRFrame.getViewerPose can return null while the session attempts to establish tracking. const pose = frame.getViewerPose(this.localReferenceSpace); if (pose) < // In mobile AR, we only have one view. const view = pose.views[0]; const viewport = this.xrSession.renderState.baseLayer.getViewport(view); this.renderer.setSize(viewport.width, viewport.height); // Use the view's transform matrix and projection matrix to configure the THREE.camera. this.camera.matrix.fromArray(view.transform.matrix); this.camera.projectionMatrix.fromArray(view.projectionMatrix); this.camera.updateMatrixWorld(true); // Render the scene with THREE.WebGLRenderer. this.renderer.render(this.scene, this.camera); >
Запустите приложение; на своем устройстве разработки посетите work/index.html . Вы должны увидеть изображение с камеры с плавающими в пространстве кубами, перспектива которых меняется при перемещении устройства. Чем больше вы перемещаетесь, тем лучше отслеживание, поэтому выясните, что подходит вам и вашему устройству.
Если у вас возникли проблемы с запуском приложения, проверьте разделы «Введение» и «Настройка среды разработки» .
После настройки базовой сцены AR пришло время начать взаимодействовать с реальным миром с помощью проверки попадания. В этом разделе вы программируете проверку попадания и используете ее для поиска поверхности в реальном мире.
Тест на попадание — это, как правило, способ провести прямую линию из точки пространства в некотором направлении и определить, пересекается ли она с какими-либо интересующими объектами. В этом примере вы нацеливаете устройство на определенное место в реальном мире. Представьте себе луч, идущий от камеры вашего устройства прямо в физический мир перед ним.
API устройства WebXR позволяет узнать, пересекал ли этот луч какие-либо объекты в реальном мире, что определяется базовыми возможностями AR и пониманием мира.
Для проведения тестов на попадание при запросе XRSession требуются дополнительные функции.
this.xrSession = await navigator.xr.requestSession("immersive-ar", < requiredFeatures: ["hit-test", "dom-overlay"] >);
this.xrSession = await navigator.xr.requestSession("immersive-ar", < requiredFeatures: ["hit-test", "dom-overlay"], domOverlay: < root: document.body >>);
ARCore работает лучше всего, когда имеется адекватное понимание окружающей среды. Это достигается с помощью процесса, называемого одновременной локализацией и картографированием (SLAM), в котором визуально различные характерные точки используются для расчета изменения местоположения и характеристик окружающей среды.
Используйте "dom-overlay" из предыдущего шага, чтобы отобразить подсказку о движении поверх потока камеры.
Добавьте в index.html со stabilization идентификатора. Этот отображает пользователям анимацию, показывающую состояние стабилизации, и предлагает им перемещаться со своим устройством, чтобы улучшить процесс SLAM. Оно отображается, когда пользователь находится в AR, и скрывается, когда прицел находит поверхность, контролируемую классами .
Используйте сетку, чтобы указать место, на которое указывает вид устройства.
setupThreeJs() < // . // this.scene = DemoUtils.createCubeScene(); this.scene = DemoUtils.createLitScene(); >
setupThreeJs() < // . // this.scene = DemoUtils.createCubeScene(); this.scene = DemoUtils.createLitScene(); this.reticle = new Reticle(); this.scene.add(this.reticle); >
Чтобы выполнить проверку попадания, вы используете новый XRReferenceSpace . Это опорное пространство указывает новую систему координат с точки зрения зрителя для создания луча, совмещенного с направлением просмотра. Эта система координат используется в XRSession.requestHitTestSource() , который может вычислять тесты попадания.
async onSessionStarted() < // . // Setup an XRReferenceSpace using the "local" coordinate system. this.localReferenceSpace = await this.xrSession.requestReferenceSpace("local"); // Add these lines: // Create another XRReferenceSpace that has the viewer as the origin. this.viewerSpace = await this.xrSession.requestReferenceSpace("viewer"); // Perform hit testing using the viewer as origin. this.hitTestSource = await this.xrSession.requestHitTestSource(< space: this.viewerSpace >); // . >
onXRFrame = (time, frame) => < // . some code omitted . this.camera.updateMatrixWorld(true); // Add the following: const hitTestResults = frame.getHitTestResults(this.hitTestSource); if (!this.stabilized && hitTestResults.length >0) < this.stabilized = true; document.body.classList.add("stabilized"); >if (hitTestResults.length > 0) < const hitPose = hitTestResults[0].getPose(this.localReferenceSpace); // update the reticle position this.reticle.visible = true; this.reticle.position.set(hitPose.transform.position.x, hitPose.transform.position.y, hitPose.transform.position.z) this.reticle.updateMatrixWorld(true); >// More code omitted. >
XRSession может генерировать события на основе взаимодействия с пользователем через событие select , которое представляет собой основное действие. В WebXR на мобильных устройствах основным действием является касание экрана.
this.xrSession.addEventListener("select", this.onSelect);
В этом примере касание экрана приводит к тому, что подсолнух помещается в прицельную сетку.
onSelect = () => < if (window.sunflower) < const clone = window.sunflower.clone(); clone.position.copy(this.reticle.position); this.scene.add(clone); >>
Вы создали прицельную марку, в которую можно прицеливаться с помощью устройства, используя тесты на попадание. Нажимая на экран, вы сможете поместить подсолнух в место, указанное сеткой.
Создание реалистичной сцены включает в себя такие элементы, как правильное освещение и тени на цифровых объектах, которые добавляют реалистичности и погружения в сцену.
Освещение и тени обрабатываются three.js . Вы можете указать, какие источники света должны отбрасывать тени, какие материалы должны получать и отображать эти тени, а также какие сетки могут отбрасывать тени. Сцена этого приложения содержит источник света, отбрасывающий тень, и плоскую поверхность для рендеринга только теней.
setupThreeJs()
В этом примере используется жестко запрограммированное положение света для теней. В будущем функции AR для WebXR могут включать оценку освещенности и другие значения, чтобы тени 3D-модели также синхронизировались с реальным миром. Дополнительную информацию см. в разделе «Функция: оценка освещения AR WebXR» .
Пример сцены, созданной в DemoUtils.createLitScene() содержит объект с shadowMesh — плоскую горизонтальную поверхность, которая отображает только тени. Эта поверхность изначально имеет позицию Y , равную 10 000 единиц. После размещения подсолнуха переместите shadowMesh на ту же высоту, что и реальная поверхность, чтобы тень цветка отображалась поверх реальной земли.
onSelect = () => < if (window.sunflower) < const clone = window.sunflower.clone(); clone.position.copy(this.reticle.position); this.scene.add(clone); const shadowMesh = this.scene.children.find(c =>c.name === "shadowMesh"); shadowMesh.position.y = clone.position.y; > >
Возможно, вам придется использовать больше возможностей понимания сцены, чтобы отображать более сложные сцены и точные тени.
Размещая подсолнух, вы должны видеть, как он отбрасывает тень. Если у вас возникнут какие-либо проблемы, проверьте код final/app.js чтобы увидеть рабочий пример этого шага.
Поздравляем! Вы завершили эту лабораторную работу по дополненной реальности с помощью WebXR.
Если не указано иное, контент на этой странице предоставляется по лицензии Creative Commons "С указанием авторства 4.0", а примеры кода – по лицензии Apache 2.0. Подробнее об этом написано в правилах сайта. Java – это зарегистрированный товарный знак корпорации Oracle и ее аффилированных лиц.