Realidade aumentada para a Web

Joe Medley
Joe Medley

No Chrome 67, anunciamos a API WebXR Device para realidade aumentada (RA) e realidade virtual (RV), mas apenas os recursos de RV foram ativados. A RV é uma experiência baseada apenas no que está em um dispositivo de computação. A RA, por outro lado, permite renderizar objetos virtuais no mundo real. Para permitir o posicionamento e o rastreamento desses objetos, adicionamos a API WebXR Hit Test ao Chrome Canary, um novo método que ajuda o código da Web imersiva a posicionar objetos no mundo real.

Onde posso conseguir isso?

Essa API vai permanecer no Canary no futuro imediato. Queremos um período de teste prolongado porque essa é uma proposta de API muito nova e queremos garantir que ela seja robusta e adequada para os desenvolvedores.

Além do Chrome Canary, você também vai precisar de:

Com isso, você pode conferir as demonstrações ou testar nosso codelab.

É só a Web

No Google I/O deste ano, demonstramos a realidade aumentada com uma versão inicial do Chrome. Durante esses três dias, eu disse repetidamente a desenvolvedores e não desenvolvedores algo que gostaria de ter colocado no meu artigo sobre a Web imersiva: "É só a Web".

"Qual extensão do Chrome preciso instalar?" "Não há extensão. É só a Web."

"Preciso de um navegador especial?" "É só a Web."

"Qual app preciso instalar?" "Não há um app especial. É apenas a Web."

Isso pode ser óbvio para você, já que você está lendo isso em um site dedicado à Web. Se você criar demonstrações com essa nova API, prepare-se para essa pergunta. Você vai receber muitas.

Falando em IO, se você quiser saber mais sobre a Web imersiva em geral, onde ela está, para onde ela está indo, confira este vídeo.

Qual é a utilidade disso?

A realidade aumentada será um recurso valioso para muitas páginas da Web. Por exemplo, ele pode ajudar as pessoas a aprender em sites educacionais e permitir que compradores em potencial visualizem objetos na casa enquanto fazem compras.

Nossas demonstrações ilustram isso. Eles permitem que os usuários coloquem uma representação em tamanho real de um objeto como se fosse real. Depois de colocada, a imagem permanece na superfície selecionada, aparece com o tamanho que teria se o item real estivesse nessa superfície e permite que o usuário se mova ao redor dela, bem como se aproximar ou se afastar dela. Isso dá aos espectadores uma compreensão mais profunda do objeto do que é possível com uma imagem bidimensional.

Se você não tem certeza do que quero dizer com tudo isso, vai ficar claro quando você usar as demonstrações. Se você não tiver um dispositivo que possa executar a demonstração, confira o link do vídeo na parte de cima deste artigo.

Uma coisa que a demonstração e o vídeo não mostram é como a RA pode transmitir o tamanho de um objeto real. O vídeo mostra uma demonstração educacional que criamos chamada Chacmool. Um artigo complementar descreve essa demonstração em detalhes. O importante para esta discussão é que, ao colocar a estátua de Chacmool na realidade aumentada, você vê o tamanho dela como se ela estivesse realmente no ambiente com você.

O exemplo de Chacmool é educacional, mas poderia ser comercial. Imagine um site de compras de móveis que permite colocar um sofá na sua sala de estar. O aplicativo de RA informa se o sofá cabe no seu espaço e como ele fica ao lado dos outros móveis.

Raios, testes de acerto e retículas

Um problema importante a ser resolvido ao implementar a RA é como colocar objetos em uma visualização do mundo real. O método para fazer isso é chamado de ray casting. O ray casting significa calcular a interseção entre o ray pointer e uma superfície no mundo real. Essa interseção é chamada de hit, e determinar se um hit ocorreu é um teste de hit.

É uma boa hora para testar o novo exemplo de código no Chrome Canary. Antes de fazer qualquer coisa, verifique se as flags corretas estão ativadas. Agora carregue o exemplo e clique em "Iniciar RA".

Observe algumas coisas. Primeiro, o medidor de velocidade, que você pode reconhecer das outras amostras imersivas, mostra 30 frames por segundo em vez de 60. Essa é a taxa em que a página da Web recebe imagens da câmera.

A RA é executada a 30 quadros por segundo

Demonstração do teste de hit de RA

A outra coisa que você precisa notar é a imagem de girassol. Ele se move conforme você se move e se encaixa em superfícies como pisos e mesas. Se você tocar na tela, um girassol será colocado em uma superfície, e um novo girassol se moverá com seu dispositivo.

A imagem que se move com o dispositivo e que tenta se fixar nas superfícies é chamada de retículo. Uma retícula é uma imagem temporária que ajuda a posicionar um objeto na realidade aumentada. Nesta demonstração, o retículo é uma cópia da imagem a ser colocada. Mas não precisa ser. Na demonstração do Chacmool, por exemplo, é uma caixa retangular com aproximadamente a mesma forma da base do objeto que está sendo colocado.

O código

A demonstração do Chacmool mostra como a RA pode ser usada em um app de produção. Felizmente, há uma demonstração muito mais simples no repositório de amostras do WebXR. Meu código de exemplo vem da demonstração AR Hit Test neste repositório. Para sua informação, gosto de simplificar exemplos de código para ajudar você a entender o que está acontecendo.

Os conceitos básicos de entrada em uma sessão de RA e execução de um loop de renderização são os mesmos para RA e RV. Leia meu artigo anterior se você não conhece o assunto. Para ser mais específico, entrar e executar uma sessão de RA é quase igual a entrar em uma sessão de janela mágica de RV. Assim como em uma janela mágica, o tipo de sessão precisa ser não imersivo, e o frame do tipo de referência precisa ser 'eye-level'.

A nova API

Agora vou mostrar como usar a nova API. Lembre-se de que, em RA, a retícula tenta encontrar uma superfície antes que um item seja colocado. Isso é feito com um teste de acerto. Para fazer um teste de hit, chame XRSession.requestHitTest(). Esta é a aparência dela:

xrSession.requestHitTest(origin, direction, frameOfReference)
.then(xrHitResult => {
  //
});

Os três argumentos desse método representam um feixe de raios. O feixe de raios é definido por dois pontos no raio (origin e direction) e de onde esses pontos são calculados (frameOfReference). A origem e a direção são vetores 3D. Independente do valor enviado, ele será normalizado (convertido) para um comprimento de 1.

Como mover o retículo

À medida que você move o dispositivo, a retícula precisa se mover com ele enquanto tenta encontrar um local onde um objeto possa ser colocado. Isso significa que a retícula precisa ser redesenhada em cada frame.

Comece com o callback requestAnimationFrame(). Assim como na RV, você precisa de uma sessão e uma pose.

function onXRFrame(t, frame) {
  let xrSession = frame.session;
  // The frame of reference, which was set elsewhere, is 'eye-level'.
  // See onSessionStarted() ins the sample code for details.
  let xrPose = frame.getDevicePose(xrFrameOfRef);
  if (xrPose && xrPose.poseModelMatrix) {
    // Do the hit test and draw the reticle.
  }
}

Depois de definir a sessão e a pose, determine onde o feixe está sendo transmitido. O exemplo de código usa a biblioteca matemática gl-matrix. Mas o gl-matrix não é um requisito. O importante é saber o que você está calculando com ele e que ele é baseado na posição do dispositivo. Extraia a posição do dispositivo de XRPose.poseModalMatrix. Com o raycast em mãos, chame requestHitTest().

function onXRFrame(t, frame) {
  let xrSession = frame.session;
  // The frame of reference, which was set elsewhere, is 'eye-level'.
  // See onSessionStarted() ins the sample code for details.
  let xrPose = frame.getDevicePose(xrFrameOfRef);
  if (xrPose && xrPose.poseModelMatrix) {
    // Calculate the origin and direction for the raycast.
    xrSession.requestHitTest(rayOrigin, rayDirection, xrFrameOfRef)
    .then((results) => {
      if (results.length) {
        // Draw for each view.
      }
    });
  }
  session.requestAnimationFrame(onXRFrame);
}

Embora não seja tão óbvio na amostra de teste de acerto, você ainda precisa refazer as visualizações para desenhar a cena. A renderização é feita usando APIs WebGL. Você pode fazer isso se for realmente ambicioso. No entanto, recomendamos usar um framework. Os exemplos de Web imersiva usam um criado apenas para as demonstrações, chamado Cottontail, e o Three.js oferece suporte ao WebXR desde maio.

Como posicionar um objeto

Um objeto é colocado em RA quando o usuário toca na tela. Para isso, use o evento select. O importante nesta etapa é saber onde colocá-lo. Como a mira móvel fornece uma fonte constante de testes de acerto, a maneira mais simples de colocar um objeto é desenhá-lo no local da mira no último teste de acerto. Se você precisar, por exemplo, se tiver um motivo legítimo para não mostrar uma retícula, chame requestHitTest() no evento de seleção conforme mostrado no exemplo.

Conclusão

A melhor maneira de entender isso é seguir o exemplo de código ou testar o codelab. Espero ter fornecido informações suficientes para que você entenda os dois.

Não vamos parar de criar APIs da Web imersiva. Publicaremos novos artigos aqui à medida que progredirmos.