Vista de superposición de WebGL

Organiza tus páginas con colecciones Guarda y categoriza el contenido según tus preferencias.

Ver muestra

Con WebGL Overlay View, puedes agregar contenido a tus mapas directamente con WebGL o bibliotecas de gráficos populares, como Three.js. La vista de superposición de WebGL brinda acceso directo al mismo contexto de renderización de WebGL que usa Google Maps Platform para renderizar el mapa base vectorial. Este uso de un contexto de renderización compartido proporciona beneficios como la oclusión de la profundidad con la geometría de los edificios 3D y la capacidad de sincronizar el contenido 2D/3D con el procesamiento del mapa base. Los objetos renderizados con la vista de superposición de WebGL también pueden vincularse a coordenadas de latitud y longitud, por lo que se mueven cuando arrastras, acercas, desplazas o inclinas el mapa.

Requisitos

Para usar la vista de superposición de WebGL, debes cargar el mapa usando un ID de mapa con el mapa vectorial habilitado. Te recomendamos que habilites la inclinación y la rotación cuando crees el ID de mapa, a fin de permitir el control total de la cámara 3D. Consulta la descripción general para obtener más información.

Cómo agregar la vista de superposición de WebGL

Para agregar la superposición a tu mapa, implementa google.maps.WebGLOverlayView y, luego, pasa tu instancia de mapa con 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);

Enlaces de ciclo de vida

La vista de superposición de WebGL proporciona un conjunto de hooks que se llaman varias veces en el ciclo de vida del contexto de renderización de WebGL del mapa base vectorial. En estos hooks de ciclo de vida, puedes configurar, dibujar y eliminar todo lo que quieras renderizar en la superposición.

  • Se llama a onAdd() cuando se crea la superposición. Úsala para recuperar o crear estructuras de datos intermedias antes de dibujar la superposición que no requiere acceso inmediato al contexto de renderización de WebGL.
  • Se llama a onContextRestored({gl}) una vez que el contexto de renderización está disponible. Úsala para inicializar o vincular cualquier estado de WebGL, como sombreadores, objetos de búfer de GL, etcétera. onContextRestored() toma una instancia de WebGLStateOptions, que tiene un solo campo:
    • gl es un controlador para el WebGLRenderingContext que usa el mapa base.
  • onDraw({gl, transformer}) renderiza la escena en el mapa base. Los parámetros para onDraw() es un objeto WebGLDrawOptions, que tiene dos campos:
    • gl es un controlador para el WebGLRenderingContext que usa el mapa base.
    • transformer proporciona funciones auxiliares para transformar de coordenadas de mapa a una matriz de proyección de vista de modelo, que se puede usar para traducir coordenadas de mapa al espacio del mundo, el espacio de la cámara y el espacio de la pantalla.
  • Se llama a onContextLost() cuando se pierde el contexto de renderización por algún motivo y es donde debes limpiar cualquier estado de GL preexistente, ya que no es necesario.
  • onStateUpdate({gl}) actualiza el estado de GL fuera del bucle de renderización y se invoca cuando se llama a requestStateUpdate. Toma una instancia de WebGLStateOptions, que tiene un solo campo:
    • gl es un controlador para el WebGLRenderingContext que usa el mapa base.
  • Se llama a onRemove() cuando se quita la superposición del mapa con WebGLOverlayView.setMap(null) y es donde debes quitar todos los objetos intermedios.

Por ejemplo, la siguiente es una implementación básica de todos los 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);

Cómo restablecer el estado de GL

La vista de superposición de WebGL expone el contexto de renderización de WebGL del mapa base. Por lo tanto, es muy importante que restablezcas el estado de GL a su estado original cuando termines de renderizar objetos. Si no se restablece el estado de GL, es probable que se generen conflictos de estado de GL, lo que hará que falle la renderización del mapa y de los objetos que especifiques.

El restablecimiento del estado de GL normalmente se maneja en el hook onDraw(). Por ejemplo, Three.js proporciona una función auxiliar que borra cualquier cambio en el estado de GL:

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

Si el mapa o los objetos no se procesan, es muy probable que no se haya restablecido el estado de GL.

Coordinar transformaciones

La posición de un objeto en el mapa vectorial se especifica proporcionando una combinación de coordenadas de latitud y longitud, así como una altitud. Sin embargo, los gráficos 3D, sin embargo, se especifican en el espacio mundial, el espacio de la cámara o el espacio de la pantalla. Para facilitar la transformación de las coordenadas del mapa en estos espacios más usados, la vista de superposición de WebGL proporciona la función auxiliar coordinateTransformer.fromLatLngAltitude(latLngAltitude, rotationArr, scalarArr) en el hook onDraw() que toma lo siguiente y muestra un Float64Array:

  • latLngAltitude: Coordenadas de latitud, longitud y altitud como LatLngAltitude o LatLngAltitudeLiteral
  • rotationArr: Float32Array de los ángulos de rotación de Euler especificados en grados.
  • scalarArr: Float32Array de escalares para aplicar al eje cardinal.

Por ejemplo, lo siguiente usa fromLatLngAltitude() para crear una matriz de proyección de cámara en 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);

Ejemplo

El siguiente es un ejemplo simple de cómo usar Three.js, una popular biblioteca de código abierto de WebGL, para colocar un objeto 3D en el mapa. Para obtener una explicación completa sobre cómo usar la vista de superposición de WebGL a fin de compilar el ejemplo que se muestra en la parte superior de esta página, prueba el codelab Cómo crear experiencias de mapa aceleradas con 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);