תצוגת שכבת-על WebGL

לצפייה בדוגמה

עם תצוגת שכבת-על WebGL תוכל להוסיף תוכן למפות שלך ישירות באמצעות WebGL, או ספריות גרפיות פופולריות, כמו Three.js. שכבת על מבוססת-WebGL מספקת גישה לאותו WebGL של עיבוד הקשר שבו הפלטפורמה של מפות Google משתמשת כדי לעבד את מפת הבסיס הווקטורית. לשימוש בהקשר של רינדור משותף יש יתרונות כגון חסימת עומק עם גיאומטריה של בניינים בתלת ממד, ויכולת לסנכרן דו-ממד/תלת-ממד. תוכן עם עיבוד מפה בסיסית. אובייקטים שעברו רינדור באמצעות תצוגת שכבת-על של WebGL יכולים יהיו מקושרות גם לקואורדינטות של קו אורך/רוחב, כך שהן יזוזו כשאתם גוררים, שינוי מרחק התצוגה, הזזה או הטיה של המפה.

דרישות

כדי להשתמש בתצוגת שכבת-על של WebGL, צריך לטעון את המפה באמצעות מזהה מפה עם הווקטור המפה מופעלת. מומלץ מאוד להפעיל הטיה וסיבוב כשיוצרים מזהה המפה, כדי לאפשר שליטה מלאה במצלמה בתלת-ממד. פרטים נוספים זמינים בסקירה הכללית.

הוספה של תצוגת שכבת-על מבוססת-WebGL

כדי להוסיף את שכבת-העל למפה, צריך להטמיע את google.maps.WebGLOverlayView ואז מעבירים אותו באמצעות מופע המפה 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);

קטעי הוק (hooks) במחזור החיים

שכבת על מבוססת-WebGL מספקת קבוצה של קטעי הוק (hooks) שמופעלים בזמנים שונים מחזור החיים של ה-WebGL של עיבוד ההקשר של מפת הבסיס הווקטורית. האלה קטעי הוק (hooks) במחזור החיים הם המקום שבו מגדירים, משרטטים ומפרקים כל דבר שרוצים מעובדת בשכבת-העל.

  • הפונקציה onAdd() מופעלת כששכבת-העל נוצרת. להשתמש בו כדי לאחזר או ליצור מבני נתונים מתווכים לפני ציור שכבת-העל, נדרשת גישה מיידית להקשר של עיבוד WebGL.
  • הפונקציה onContextRestored({gl}) מופעלת ברגע שההקשר של הרינדור זמינים. אפשר להשתמש בו כדי לאתחל או לקשר כל מצב WebGL, כמו תוכנות הצללה (shader), GL של מאגרי נתונים זמניים וכו'. onContextRestored() לוקח WebGLStateOptions שמכיל שדה אחד:
    • gl הוא נקודת אחיזה של WebGLRenderingContext שמשמשת את המפה הבסיסית.
  • onDraw({gl, transformer}) מעבד את הסצנה במפה הבסיסית. הפרמטרים של onDraw() הם אובייקט WebGLDrawOptions שכולל שני שדות:
    • gl הוא נקודת אחיזה של WebGLRenderingContext שמשמשת את המפה הבסיסית.
    • transformer מספק פונקציות מסייעות לביצוע טרנספורמציה מהמפה למטריצת היטל-ראייה של מודל, שבהן ניתן להשתמש לתרגם את הקואורדינטות של המפה לשטח העולמי, למצלמה ולמסך המרחב המשותף.
  • קוראים לפונקציה onContextLost() אם מאבדים את ההקשר של הרינדור ושבו צריך לנקות כל מצב GL קיים, אינה נחוצה יותר.
  • onStateUpdate({gl}) מעדכן את מצב ה-GL מחוץ ללולאת העיבוד, והוא מופעל כשמתבצעת קריאה אל requestStateUpdate. נדרש מופע WebGLStateOptions, שמכיל שדה אחד:
    • gl הוא נקודת אחיזה של WebGLRenderingContext שמשמשת את המפה הבסיסית.
  • הפונקציה onRemove() מופעלת כאשר מסירים את שכבת-העל מהמפה באמצעות WebGLOverlayView.setMap(null), ושבו צריך להסיר את כל של אובייקטי ביניים.

לדוגמה, הדוגמה הבאה היא הטמעה בסיסית של כל ההוקים (hooks) של מחזור החיים:

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

איפוס מצב GL

תצוגת שכבת-על של WebGL חושפת את הקשר עיבוד ה-WebGL של המפה הבסיסית. כי חשוב מאוד לאפס את מצב ה-GL המקורי אחרי שסיימתם לעבד את האובייקטים. איפוס מצב ה-GL נכשל עלולות לגרום להתנגשות במצב GL, מה שיגרום לעיבוד וכל האובייקטים שציינת ייכשלו.

בדרך כלל, איפוס של מצב GL מטופל בהוק (hook) onDraw(). לדוגמה, Three.js מספק פונקציית עזר שמנקה את כל השינויים במצב GL:

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

אם לא ניתן לעבד את המפה או האובייקטים, סביר מאוד שמצב ה-GL לא אופס.

תיאום טרנספורמציות

המיקום של אובייקט במפת הווקטור נקבע על ידי מתן שילוב של קואורדינטות של קו רוחב וקו אורך, וגם גובה. תלת-ממד עם זאת, מצוין במרחב העולם, במרחב המצלמה או בשטח המסך. כדי שיהיה קל יותר לשנות קואורדינטות במפה למיקומים נפוצים בשכבת-על של WebGL פונקציית העוזר coordinateTransformer.fromLatLngAltitude(latLngAltitude, rotationArr, scalarArr) מופיעה בהוק (hook) onDraw() שלוקח את הפקודות הבאות וגם הפונקציה מחזירה את הערך Float64Array:

  • latLngAltitude: קואורדינטות של קו רוחב/אורך/גובה LatLngAltitude או LatLngAltitudeLiteral.
  • rotationArr: Float32Array של זוויות הסיבוב של אולר המצוינות במעלות.
  • scalarArr: Float32Array מהסקלרים שיש להחיל על הציר הקרדינלי.

לדוגמה, המשתמשים הבאים משתמשים ב-fromLatLngAltitude() כדי ליצור מצלמה מטריצת ההיטל ב-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);

דוגמה

הדוגמה הבאה היא לשימוש ב-Three.js, ספריית WebGL פופולרית בקוד פתוח, כדי למקם אובייקט תלת-ממדי במפה. עבור הדרכה מפורטת מלאה לשימוש בתצוגת שכבת-על של WebGL כדי לבנות את הדוגמה שאתם רואים פועלים בחלק העליון של הדף הזה, יצירת קוד Lab לחוויות מפה עם האצת 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);