Visualização de sobreposição do WebGL

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

Ver amostra

Com a visualização de sobreposição do WebGL, você pode adicionar conteúdo aos mapas usando diretamente WebGL ou bibliotecas de gráficos famosos, como o three.js. A visualização de sobreposição do WebGL fornece acesso direto ao mesmo contexto de renderização WebGL usado pela Plataforma Google Maps para renderizar o mapa básico vetorial. Esse uso de um contexto de renderização compartilhada oferece benefícios como a oclusão de profundidade com geometria de construção 3D e a capacidade de sincronizar conteúdo 2D/3D com a renderização do mapa básico Os objetos renderizados com a visualização de sobreposição do WebGL também podem ser vinculados a coordenadas de latitude/longitude. Dessa forma, eles se movem quando você arrasta, aplica zoom, movimenta ou inclina o mapa.

Requisitos

Para usar a visualização de sobreposição do WebGL, você precisa carregar o mapa usando um ID com o mapa vetorial ativado. É altamente recomendável ativar a inclinação e a rotação ao criar o ID do mapa para permitir o controle total da câmera 3D. Confira a visão geral para saber mais.

Adicionar visualização de sobreposição do WebGL

Para adicionar a sobreposição ao mapa, implemente google.maps.WebGLOverlayView e, em seguida, transmita a instância do mapa usando setMap:

// Create a map instance.
const map = new google.maps.Map(mapDiv, mapOptions);

// Create a WebGL Overlay View instance.
const webglOverlayView = new google.maps.WebGLOverlayView();

// Add the overlay to the map.
webglOverlayView.setMap(map);

Ganchos do ciclo de vida

A visualização de sobreposição do WebGL fornece um conjunto de hooks chamados várias vezes no ciclo de vida do contexto de renderização WebGL do mapa básico vetorial. Esses ganchos de ciclo de vida são onde você configura, desenha e desmonta tudo o que quiser renderizar na sobreposição.

  • onAdd() é chamado quando a sobreposição é criada. Use-a para buscar ou criar estruturas de dados intermediárias antes da exibição da sobreposição que não exigem acesso imediato ao contexto de renderização WebGL.
  • onContextRestored({gl}) é chamado quando o contexto de renderização está disponível. Use-o para inicializar ou vincular qualquer estado WebGL, como sombreadores, objetos de buffer GL e assim por diante. onContextRestored() usa uma instância de WebGLStateOptions, que tem um único campo:
    • gl é um identificador para o WebGLRenderingContext usado pelo mapa básico.
  • onDraw({gl, transformer}) renderiza a cena no mapa básico. Os parâmetros de onDraw() são um objeto WebGLDrawOptions, que tem dois campos:
    • gl é um identificador para o WebGLRenderingContext usado pelo mapa básico.
    • O transformer fornece funções auxiliares para transformar as coordenadas do mapa em matrizes de projeção de modelo e visualização, que podem ser usadas para converter coordenadas em mapas no espaço mundial, o espaço da câmera e o espaço da tela.
  • O onContextLost() é chamado quando o contexto de renderização é perdido por qualquer motivo e é para limpar qualquer estado GL preexistente, já que ele não é mais necessário.
  • A onStateUpdate({gl}) atualiza o estado GL fora do loop de renderização e é invocada quando requestStateUpdate é chamado. Ele usa uma instância de WebGLStateOptions, que tem um único campo:
    • gl é um identificador para o WebGLRenderingContext usado pelo mapa básico.
  • onRemove() é chamado quando a sobreposição é removida do mapa com WebGLOverlayView.setMap(null) e é onde você deve remover todos os objetos intermediários.

O exemplo a seguir é uma implementação básica de todos os hooks de ciclo de vida:

const webglOverlayView = new google.maps.WebGLOverlayView();

webglOverlayView.onAdd = () => {
  // Do setup that does not require access to rendering context.
}

webglOverlayView.onContextRestored = ({gl}) => {
  // Do setup that requires access to rendering context before onDraw call.
}

webglOverlayView.onStateUpdate = ({gl}) => {
  // Do GL state setup or updates outside of the render loop.
}

webglOverlayView.onDraw = ({gl, transformer}) => {
  // Render objects.
}

webglOverlayView.onContextLost = () => {
  // Clean up pre-existing GL state.
}

webglOverlayView.onRemove = () => {
  // Remove all intermediate objects.
}

webglOverlayView.setMap(map);

Como redefinir o estado do GL

A visualização de sobreposição do WebGL expõe o contexto de renderização WebGL do mapa básico. Por isso, é extremamente importante redefinir o estado do GL para o estado original quando você terminar de renderizar objetos. Falha ao redefinir o estado do GL provavelmente resultará em conflitos de estado GL, o que fará com que a renderização do mapa e de todos os objetos especificados falhe.

A redefinição do estado GL normalmente é processada no hook onDraw(). Por exemplo, o three.js oferece uma função auxiliar que limpa todas as mudanças no estado GL:

webglOverlayView.onDraw = ({gl, transformer}) => {
  // Specify an object to render.
  renderer.render(scene, camera);
  renderer.resetState();
}

Se o mapa ou os objetos não forem renderizados, é muito provável que o estado GL não tenha sido redefinido.

Transformações das coordenadas

A posição de um objeto no mapa vetorial é especificada pelo fornecimento de uma combinação de coordenadas de latitude e longitude e de altitude. No entanto, os gráficos 3D são especificados no espaço mundial, no espaço da câmera ou no espaço na tela. Para facilitar a transformação de coordenadas de mapa nesses espaços mais usados, a visualização de sobreposição do WebGL fornece a função auxiliar coordinateTransformer.fromLatLngAltitude(latLngAltitude, rotationArr, scalarArr) no hook onDraw() que usa o seguinte e retorna um Float64Array:

  • latLngAltitude: coordenadas de latitude/longitude/altitude como LatLngAltitude ou LatLngAltitudeLiteral.
  • rotationArr: Float32Array dos ângulos de rotação de euler especificados em graus.
  • scalarArr: Float32Array dos escalares para aplicar ao eixo cardeal.

Por exemplo, o comando a seguir usa fromLatLngAltitude() para criar uma matriz de projeção de câmera no three.js:

const camera = new THREE.PerspectiveCamera();
const matrix = coordinateTransformer.fromLatLngAltitude({
    lat: mapOptions.center.lat,
    lng: mapOptions.center.lng,
    altitude: 120,
});
camera.projectionMatrix = new THREE.Matrix4().fromArray(matrix);

Exemplo

Veja a seguir um exemplo simples do uso do Three.js, uma biblioteca WebGL famosa e de código aberto, para colocar um objeto 3D no mapa. Para ver um tutorial completo sobre como usar a visualização de sobreposição do WebGL para criar o exemplo exibido no topo desta página, consulte o codelab Como criar experiências de mapa aceleradas por WebGL.

const webglOverlayView = new google.maps.WebGLOverlayView();
let scene, renderer, camera, loader;

webglOverlayView.onAdd = () => {
  // Set up the Three.js scene.
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera();
  const ambientLight = new THREE.AmbientLight( 0xffffff, 0.75 ); // Soft white light.
  scene.add(ambientLight);

  // Load the 3D model with GLTF Loader from Three.js.
  loader = new GLTFLoader();
  loader.load("pin.gltf");
}

webglOverlayView.onContextRestored = ({gl}) => {
  // Create the Three.js renderer, using the
  // maps's WebGL rendering context.
  renderer = new THREE.WebGLRenderer({
    canvas: gl.canvas,
    context: gl,
    ...gl.getContextAttributes(),
  });
  renderer.autoClear = false;
}

webglOverlayView.onDraw = ({gl, transformer}) => {
  // Update camera matrix to ensure the model is georeferenced correctly on the map.
  const matrix = transformer.fromLatLngAltitude({
      lat: mapOptions.center.lat,
      lng: mapOptions.center.lng,
      altitude: 120,
  });
camera.projectionMatrix = new THREE.Matrix4().fromArray(matrix);

  // Request a redraw and render the scene.
  webglOverlayView.requestRedraw();
  renderer.render(scene, camera);

  // Always reset the GL state.
  renderer.resetState();
}

// Add the overlay to the map.
webglOverlayView.setMap(map);