Реалізація WebXR (VR/AR в браузері) на сайті

Коли користувач натискає «Переглянути в AR», але на його пристрої нічого не відбувається, це підриває довіру до вашого продукту. Ми реалізуємо WebXR-проєкти під ключ, створюючи VR та AR-досвід прямо в браузері з урахуванням усіх платформ. Наша команда забезпечує коректну роботу на кожному пристрої та подальшу підтримку, щоб ваш імерсивний контент був доступний кожному клієнту.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Реалізація WebXR (VR/AR в браузері) на сайті
Складний
від 2 тижнів до 3 місяців
Часті запитання

Реалізація WebXR (VR/AR в браузері) на сайті

Користувач відкриває сторінку на iPhone з Safari і бачить кнопку «Подивитися в AR» — але нічого не відбувається. Модель не завантажується, тому що WebXR AR не підтримується на iOS. На Android Chrome та ж модель працює ідеально. Така ситуація — типова помилка при впровадженні імерсивного досвіду: без урахування платформних відмінностей половина аудиторії залишається за бортом. Ми реалізуємо WebXR-проекти під ключ: VR та AR досвід прямо в браузері, з коректним fallback для кожного пристрою. Наш досвід — понад 50 реалізованих проектів, що підтверджує гарантію якості. Зверніться до нас — отримайте сертифіковане рішення.

Типові проблеми при впровадженні WebXR

Перша помилка — ігнорування відмінностей платформ. Android Chrome підтримує immersive-ar; iOS — лише AR Quick Look через USDZ. Без fallback користувачі iPhone бачать порожній екран. Друга — продуктивність: важкі моделі з високополігональною геометрією викликають гальма на мобільних, а неправильне налаштування LOD збільшує час завантаження в 2–3 рази. Третя — відсутність hit-testing (розміщення об'єктів на реальних поверхнях) погіршує враження від AR. Економія часу на цьому етапі обертається втратою до 40% залученості. Зв'яжіться з нами для аудиту вашої 3D-моделі — ми підкажемо, як оптимізувати її під мобільні пристрої.

Як забезпечити підтримку на всіх пристроях?

Ми використовуємо комбінований підхід: визначаємо платформу через user-agent, для Android запускаємо WebXR AR-сесію з hit-testing, для iOS показуємо посилання на USDZ через AR Quick Look. На десктопі та для VR-гарнітур — immersive-vr. Детекція реалізується в кілька рядків, як показано нижче. Рекомендується також перевіряти підтримку через navigator.xr.isSessionSupported перед показом інтерфейсу.

const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent)
const isAndroid = /Android/.test(navigator.userAgent)
if (isIOS) {
  document.getElementById('ar-link')!.style.display = 'block' // USDZ
} else if (isAndroid && await navigator.xr?.isSessionSupported('immersive-ar')) {
  document.getElementById('ar-button')!.style.display = 'block' // WebXR AR
}

Чому Three.js — найкращий вибір для кастомізації WebXR?

Three.js дає повний контроль над рендерингом, анімацією, контролерами. Він швидший за A-Frame в 2–3 рази при складній фізиці та великій кількості об'єктів. Реалізація hit-testing, ретикулів, реакції на контролери — на рівні API. A-Frame хороший для швидких прототипів, але для продакшену з унікальним UX обираємо Three.js. Альтернатива — React Three Fiber, який надає React-обгортку над Three.js та спрощує інтеграцію в сучасні проекти.

Three.js + WebXR

Three.js має вбудовану підтримку WebXR:

import * as THREE from 'three'
import { ARButton } from 'three/examples/jsm/webxr/ARButton'
import { VRButton } from 'three/examples/jsm/webxr/VRButton'
import { XRControllerModelFactory } from 'three/examples/jsm/webxr/XRControllerModelFactory'

function WebXRScene({ mode }: { mode: 'ar' | 'vr' }) {
  const mountRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    const container = mountRef.current!
    const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
    renderer.setPixelRatio(window.devicePixelRatio)
    renderer.setSize(container.clientWidth, container.clientHeight)
    renderer.xr.enabled = true
    container.appendChild(renderer.domElement)

    const scene = new THREE.Scene()
    const camera = new THREE.PerspectiveCamera(70, container.clientWidth / container.clientHeight, 0.01, 100)

    scene.add(new THREE.AmbientLight(0xffffff, 1))
    const dirLight = new THREE.DirectionalLight(0xffffff, 2)
    dirLight.position.set(0, 5, 3)
    scene.add(dirLight)

    const button = mode === 'ar'
      ? ARButton.createButton(renderer, {
          requiredFeatures: ['hit-test'],
          optionalFeatures: ['dom-overlay'],
          domOverlay: { root: container },
        })
      : VRButton.createButton(renderer)
    document.body.appendChild(button)

    if (mode === 'vr') {
      const controllerModelFactory = new XRControllerModelFactory()
      for (let i = 0; i < 2; i++) {
        const controller = renderer.xr.getController(i)
        controller.addEventListener('selectstart', onSelectStart)
        controller.addEventListener('selectend', onSelectEnd)
        scene.add(controller)

        const controllerGrip = renderer.xr.getControllerGrip(i)
        controllerGrip.add(controllerModelFactory.createControllerModel(controllerGrip))
        scene.add(controllerGrip)
      }
    }

    let hitTestSource: XRHitTestSource | null = null
    let hitTestSourceRequested = false
    const reticle = createReticle()
    scene.add(reticle)

    renderer.xr.addEventListener('sessionstart', async () => {
      if (mode !== 'ar') return
      const session = renderer.xr.getSession()!
      const viewerSpace = await session.requestReferenceSpace('viewer')
      hitTestSource = await session.requestHitTestSource!({ space: viewerSpace })!
    })

    renderer.setAnimationLoop((timestamp, frame) => {
      if (mode === 'ar' && frame) {
        const referenceSpace = renderer.xr.getReferenceSpace()!
        const hitTestResults = frame.getHitTestResults(hitTestSource!)
        if (hitTestResults.length > 0) {
          const hit = hitTestResults[0]
          const pose = hit.getPose(referenceSpace)
          if (pose) {
            reticle.visible = true
            reticle.matrix.fromArray(pose.transform.matrix)
          }
        } else {
          reticle.visible = false
        }
      }
      renderer.render(scene, camera)
    })

    function onSelectStart(event: THREE.Event) {
      if (reticle.visible) {
        const geometry = new THREE.BoxGeometry(0.1, 0.1, 0.1)
        const material = new THREE.MeshStandardMaterial({ color: 0x2563eb })
        const mesh = new THREE.Mesh(geometry, material)
        mesh.position.setFromMatrixPosition(reticle.matrix)
        mesh.quaternion.setFromRotationMatrix(reticle.matrix)
        scene.add(mesh)
      }
    }

    return () => {
      renderer.setAnimationLoop(null)
      renderer.dispose()
      button.remove()
      container.removeChild(renderer.domElement)
    }
  }, [mode])

  return (
    <div ref={mountRef} style={{ width: '100%', height: '600px', position: 'relative' }} />
  )
}

function createReticle(): THREE.Mesh {
  const geometry = new THREE.RingGeometry(0.05, 0.07, 32).rotateX(-Math.PI / 2)
  const material = new THREE.MeshBasicMaterial({ color: 0xffffff, side: THREE.DoubleSide })
  const reticle = new THREE.Mesh(geometry, material)
  reticle.matrixAutoUpdate = false
  reticle.visible = false
  return reticle
}

Порівняння підходів для AR в браузері

Параметр WebXR AR AR Quick Look A-Frame AR
Підтримка iOS Ні Так Ні
Інтерактивність Висока (hit-test, контролери) Низька (тільки перегляд) Середня (обмежена)
Складність інтеграції Середня Низька (посилання+USDZ) Низька
Продуктивність Залежить від моделі Нативна Хороша
Кастомізація Повна Мінімальна Середня

Порівняння фреймворків: Three.js vs A-Frame

Критерій Three.js A-Frame
Продуктивність Висока (до 60fps на мобільних) Середня (до 30fps на складних сценах)
Гнучкість Повний контроль над рендерингом Обмежений декларативними компонентами
Крива навчання Крута (потребує знання 3D-графіки) Полога (HTML-подібний синтаксис)
Підтримка WebXR Повна (контролери, hit-test) Базова (контролери через компоненти)

iOS: AR Quick Look

Safari iOS не підтримує WebXR AR, але підтримує AR Quick Look через USDZ-файли:

<a href="/models/product.usdz" rel="ar" id="ar-link">
  <img src="/models/product-preview.jpg" alt="Перегляд в AR" />
  <span>Подивитися у вашому інтер'єрі</span>
</a>

Конвертація 3D-моделей

Для AR Quick Look потрібен USDZ, для WebXR — GLTF. Конвертацію виконуємо через Blender або утиліти командного рядка, наприклад, usd-from-gltf. Втрата якості при правильних налаштуваннях експорту мінімальна — зазвичай менше 5%. Детальніше про формати — в офіційній документації MDN WebXR.

Приклад: оптимізація моделі перед конвертацією Для мобільних пристроїв рекомендується знижувати кількість полігонів до 50 000, використовувати текстури 1024x1024 та об'єднувати матеріали. Це зменшує розмір моделі на 60% і прискорює завантаження в 2 рази.

Що входить в роботу

  • Аналіз цільових пристроїв та платформ
  • Підготовка 3D-моделей (оптимізація під мобільні, конвертація в необхідні формати)
  • Реалізація WebXR AR/VR сцени з hit-testing та підтримкою контролерів
  • Інтеграція iOS AR Quick Look з коректним fallback
  • Тестування на реальних пристроях (Android, iPhone, Quest)
  • Передача документації та вихідних кодів
  • Навчання вашої команди роботі з рішенням

Етапи розробки

  1. Аналітика — визначаємо сценарії використання, обираємо стек (Three.js, A-Frame, React Three Fiber).
  2. Проектування — прототип взаємодії, схема сцени, оцінка бюджету.
  3. Реалізація — код WebXR, інтеграція з вашим сайтом, оптимізація продуктивності.
  4. Тестування — перевірка на гарнітурах і телефонах, виправлення помилок, замір Core Web Vitals.
  5. Деплой — налаштування HTTPS, публікація моделей, CDN для швидкого завантаження.

Терміни орієнтовно

  • AR-перегляд продукту (Android + iOS) — 5–7 днів (вартість від $1500).
  • Інтерактивна VR-сцена з контролерами — 8–12 днів (від $2500).
  • Повний цикл з кастомізацією — від 14 днів (від $4000).

Вартість розраховується індивідуально. Наші інженери мають понад 10 років досвіду в 3D-графіці та веб-розробці, що є гарантією якості. Отримайте консультацію щодо вашого проекту — ми оцінимо складність і запропонуємо оптимальне рішення.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1141
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1060