Realidade aumentada na web com WebXR

1. Introdução ao WebXR e Realidade Aumentada na Web

O WebXR Device API é um padrão da W3C que permite criar experiências imersivas diretamente no navegador, sem necessidade de instalação de aplicativos nativos. Ele unifica o desenvolvimento para Realidade Virtual (VR) e Realidade Aumentada (AR) em uma única interface.

No contexto do WebXR, a diferença fundamental entre VR e AR é que a VR cria um ambiente completamente sintético, enquanto a AR sobrepõe objetos virtuais ao mundo real capturado pela câmera do dispositivo. A AR na web oferece vantagens significativas: acessibilidade imediata (basta um link), compatibilidade cross-platform (funciona em Android, iOS e desktop com suporte), e atualização instantânea sem passar por lojas de aplicativos.

2. Configuração do Ambiente e Primeiros Passos

Para desenvolver AR com WebXR, você precisa de um navegador compatível (Chrome 79+, Edge 79+, ou navegadores mobile como Chrome Android e Safari com WebXR). Dispositivos com suporte a ARCore (Android) ou ARKit (iOS) são recomendados.

A estrutura básica de um documento HTML para WebXR inclui a declaração de permissões e a inicialização da sessão AR:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Minha Primeira AR na Web</title>
</head>
<body>
  <script>
    async function iniciarAR() {
      if (!navigator.xr) {
        console.log('WebXR não suportado');
        return;
      }

      const session = await navigator.xr.requestSession('immersive-ar', {
        requiredFeatures: ['local', 'hit-test']
      });

      console.log('Sessão AR iniciada com sucesso!');
    }

    document.addEventListener('click', iniciarAR);
  </script>
</body>
</html>

O método requestSession('immersive-ar') solicita ao navegador uma sessão AR. O parâmetro requiredFeatures define quais capacidades serão necessárias — local para rastreamento básico e hit-test para detecção de superfícies.

3. Fundamentos da Cena AR: Espaço, Câmera e Renderização

O WebXR utiliza um sistema de coordenadas baseado em espaços de referência. O espaço local posiciona a origem no local onde a sessão foi iniciada, enquanto local-floor ajusta o eixo Y para o nível do chão real.

Para renderizar objetos 3D, você pode usar WebGL diretamente ou bibliotecas como Three.js, que simplificam o processo. Exemplo com Three.js:

import * as THREE from 'three';
import { XRButton } from 'three/examples/jsm/webxr/XRButton.js';
import { XRControllerModelFactory } from 'three/examples/jsm/webxr/XRControllerModelFactory.js';

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 100);
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.xr.enabled = true;
document.body.appendChild(renderer.domElement);

// Adiciona o botão para iniciar AR
document.body.appendChild(XRButton.createButton(renderer, { 
  requiredFeatures: ['hit-test', 'local'] 
}));

A câmera virtual se integra automaticamente com a câmera real do dispositivo, permitindo que objetos 3D pareçam existir no ambiente físico.

4. Colocando Objetos no Mundo Real: Hit Testing e Âncoras

O Hit Testing é o mecanismo que detecta superfícies reais (chão, mesas, paredes) a partir do ponto de toque na tela. Com ele, podemos posicionar objetos virtuais em locais específicos do mundo real.

Exemplo prático de hit testing com Three.js:

let hitTestSource = null;
let reticle = new THREE.Mesh(
  new THREE.RingGeometry(0.15, 0.2, 32),
  new THREE.MeshBasicMaterial({ color: 0x00ff00, transparent: true, opacity: 0.5 })
);
reticle.rotation.x = -Math.PI / 2;
scene.add(reticle);

renderer.xr.addEventListener('sessionstart', async (event) => {
  const session = renderer.xr.getSession();
  const viewerSpace = await session.requestReferenceSpace('local');
  hitTestSource = await session.requestHitTestSource({ space: viewerSpace });
});

function onSelect() {
  if (reticle.visible) {
    const cube = new THREE.Mesh(
      new THREE.BoxGeometry(0.2, 0.2, 0.2),
      new THREE.MeshStandardMaterial({ color: 0xffaa00 })
    );
    cube.position.copy(reticle.position);
    cube.position.y += 0.1;
    scene.add(cube);
  }
}

renderer.xr.addEventListener('select', onSelect);

As âncoras permitem fixar objetos em posições do mundo real, mantendo-os estáveis mesmo quando o usuário se movimenta. O WebXR oferece a interface XRAnchor para esse propósito.

5. Interação do Usuário com Objetos AR

A interação em AR na web utiliza eventos de entrada como selectstart, selectend e squeeze. Para manipular objetos, podemos detectar toques e movimentos:

let selectedObject = null;
let offset = new THREE.Vector3();

renderer.xr.addEventListener('selectstart', (event) => {
  const controller = event.target;
  // Verifica colisão com objetos da cena
  const intersections = raycaster.intersectObjects(objects);
  if (intersections.length > 0) {
    selectedObject = intersections[0].object;
    offset.copy(selectedObject.position).sub(raycaster.ray.origin);
  }
});

renderer.xr.addEventListener('selectend', () => {
  selectedObject = null;
});

function animate() {
  if (selectedObject) {
    selectedObject.position.copy(raycaster.ray.origin).add(offset);
  }
  renderer.render(scene, camera);
}

Feedback visual (mudança de cor, destaque) e sonoro melhoram significativamente a experiência do usuário, tornando a interação mais natural.

6. Iluminação, Sombras e Realismo na AR

Para integrar objetos virtuais de forma convincente ao ambiente real, é crucial ajustar a iluminação virtual para corresponder à iluminação real. O WebXR fornece a XRLightEstimation para estimar a iluminação ambiente:

const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 10, 7);
light.castShadow = true;
scene.add(light);

// Ajusta sombras
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;

Para performance em dispositivos mobile, otimize assets 3D: reduza polígonos, use texturas comprimidas (KTX, Basis) e implemente Level of Detail (LOD).

7. Casos de Uso e Limitações Atuais

Aplicações reais incluem:
- Visualização de móveis (IKEA Place-like)
- Jogos educativos (sobreposição de informações em objetos reais)
- Guias turísticos com pontos de interesse virtuais

Limitações atuais:
- Rastreamento prejudicado em ambientes escuros ou com pouca textura
- Consumo elevado de bateria em dispositivos mobile
- Precisão limitada do hit testing em superfícies reflexivas

Alternativas e complementos incluem AR.js (baseado em marcadores), A-Frame (framework declarativo) e bibliotecas como Three.js que abstraem complexidades do WebXR.

8. Boas Práticas e Próximos Passos

  • Performance: reduza polígonos ao mínimo necessário, use texturas de baixa resolução (512x512 ou 1024x1024), evite overdraw e implemente LOD
  • Testes: teste em múltiplos dispositivos (Android com ARCore, iOS com ARKit) e versões de navegador
  • Acessibilidade: forneça alternativas para usuários sem suporte a AR (modo 2D)

Recursos para aprofundamento incluem a especificação W3C WebXR, documentação MDN e comunidades como o WebXR Discord.

Referências