Visualizzazione overlay WebGL

Visualizza esempio

Grazie alla visualizzazione sovrapposta di WebGL, puoi aggiungere direttamente contenuti alle mappe utilizzando WebGL, o librerie grafiche popolari come Three.js. La visualizzazione sovrapposta di WebGL offre allo stesso contesto di rendering WebGL utilizzato da Google Maps Platform per eseguire il rendering la mappa base vettoriale. L'utilizzo di un contesto di rendering condiviso offre vantaggi come l'occlusione di profondità con la geometria di edifici 3D e la possibilità di sincronizzare 2D/3D con il rendering della mappa base. Gli oggetti sottoposti a rendering con la vista sovrapposta di WebGL essere associate anche alle coordinate di latitudine/longitudine, in modo che si spostino quando trascini, eseguire lo zoom, la panoramica o l'inclinazione della mappa.

Requisiti

Per utilizzare la visualizzazione sovrapposta di WebGL, devi caricare la mappa utilizzando un ID mappa con il vettore mappa attivata. Ti consigliamo vivamente di attivare l'inclinazione e la rotazione quando crei l'ID mappa, per consentire il controllo completo della fotocamera 3D. Consulta la panoramica per i dettagli.

Aggiungi vista sovrapposta WebGL

Per aggiungere l'overlay alla mappa, implementa google.maps.WebGLOverlayView, poi passala alla tua istanza di mappa utilizzando 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);

Hook ciclo di vita

La visualizzazione sovrapposta di WebGL fornisce una serie di hook che vengono chiamati in diversi momenti nelle il ciclo di vita del contesto di rendering WebGL della mappa base vettoriale. Questi Gli hook del ciclo di vita sono il punto in cui configuri, disegna e rimuovi tutto ciò che vuoi visualizzati nell'overlay.

  • onAdd() viene chiamato quando viene creato l'overlay. Utilizzala per recuperare o creare strutture di dati intermedie prima di disegnare l'overlay che non richiedono l'accesso immediato al contesto di rendering di WebGL.
  • onContextRestored({gl}) viene chiamato una volta che il contesto di rendering è disponibili. Utilizzalo per inizializzare o associare qualsiasi stato WebGL, ad esempio Shader, GL oggetti buffer e così via. onContextRestored() prende WebGLStateOptions , che ha un solo campo:
      .
    • gl è un handle per il valore WebGLRenderingContext utilizzato dalla mappa base.
  • onDraw({gl, transformer}) esegue il rendering della scena sulla mappa base. Il parametro per onDraw() è un oggetto WebGLDrawOptions, che ha due campi:
      .
    • gl è un handle per il valore WebGLRenderingContext utilizzato dalla mappa base.
    • transformer fornisce funzioni helper per la trasformazione dalla mappa le coordinate alla matrice modello-vista-proiezione, che può essere utilizzata traduci le coordinate della mappa nello spazio mondiale, nello spazio della fotocamera e sullo schermo spazio.
  • onContextLost() viene chiamato quando il contesto di rendering viene perso per qualsiasi ed è il punto in cui occorre ripulire qualsiasi stato GL preesistente, poiché non è più necessario.
  • onStateUpdate({gl}) aggiorna lo stato GL al di fuori del loop di rendering, e viene richiamato quando viene chiamato requestStateUpdate. Richiede un WebGLStateOptions, che ha un solo campo:
    • gl è un handle per il valore WebGLRenderingContext utilizzato dalla mappa base.
  • onRemove() viene chiamato quando l'overlay viene rimosso dalla mappa con WebGLOverlayView.setMap(null), dove devi rimuovere tutti oggetti intermedi.

Ad esempio, di seguito è riportata un'implementazione di base di tutti gli hook del ciclo di vita:

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);

Reimpostazione dello stato GL

La visualizzazione sovrapposta di WebGL mostra il contesto di rendering WebGL della mappa base. Poiché di questo, è estremamente importante reimpostare lo stato GL al suo originale al termine del rendering degli oggetti. La mancata reimpostazione dello stato GL è causerà conflitti di stato GL, che comporteranno il rendering di entrambi e la mappatura di eventuali oggetti specificati non riusciranno.

La reimpostazione dello stato GL viene solitamente gestita nell'hook onDraw(). Ad esempio: Three.js fornisce una funzione helper che cancella eventuali modifiche allo stato GL:

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

Se non viene eseguito il rendering della mappa o degli oggetti, è molto probabile che lo stato GL non è stato reimpostato.

Coordina le trasformazioni

La posizione di un oggetto sulla mappa vettoriale viene specificata fornendo una combinazione di coordinate di latitudine e longitudine, nonché dell'altitudine. 3D le immagini sono invece specificate nello spazio globale, nella fotocamera o sullo schermo. Per semplificare la trasformazione delle coordinate della mappa in queste più comuni spazi, la vista sovrapposta di WebGL offre Funzione helper coordinateTransformer.fromLatLngAltitude(latLngAltitude, rotationArr, scalarArr) nell'hook onDraw() che accetta quanto segue e restituisce un Float64Array:

  • latLngAltitude: coordinate di latitudine/longitudine/altitudine come LatLngAltitude o LatLngAltitudeLiteral.
  • rotationArr: Float32Array degli angoli di rotazione euler specificati in gradi.
  • scalarArr: Float32Array di scalari da applicare all'asse cardinale.

Ad esempio, l'esempio seguente utilizza fromLatLngAltitude() per creare una videocamera matrice di proiezione in 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);

Esempio

Di seguito è riportato un semplice esempio di utilizzo di Three.js, una nota libreria open source WebGL per posizionare un oggetto 3D sulla mappa. Per un procedura dettagliata completa sull'utilizzo della vista sovrapposta di WebGL per creare l'esempio visualizzato in esecuzione nella parte superiore di questa pagina, prova Creazione di un codelab relativo alle esperienze sulle mappe con accelerazione 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);