มุมมองการวางซ้อนของ WebGL ช่วยให้คุณเพิ่มเนื้อหาลงในแผนที่ได้โดยใช้ WebGL โดยตรง หรือใช้ไลบรารีกราฟิกยอดนิยมอย่าง Three.js มุมมองการวางซ้อนของ WebGL ช่วยให้เข้าถึงบริบทการแสดงภาพ WebGL เดียวกันกับที่ Google Maps Platform ใช้ในการแสดงผลแผนที่ฐานแบบเวกเตอร์ได้โดยตรง การใช้บริบทการแสดงภาพร่วมกันนี้มีสิทธิประโยชน์ เช่น การบดบังความลึกด้วยรูปทรงเรขาคณิตของสิ่งปลูกสร้าง 3 มิติ และความสามารถในการซิงค์เนื้อหา 2 มิติ/3 มิติกับการแสดงผลแผนที่ฐาน นอกจากนี้ยังสามารถเชื่อมโยงออบเจ็กต์ที่แสดงผลด้วยมุมมองการวางซ้อนของ WebGL กับพิกัดละติจูด/ลองจิจูดได้ด้วย ดังนั้นออบเจ็กต์จะเคลื่อนที่เมื่อคุณลาก ซูม เลื่อน หรือเอียงแผนที่
ข้อกำหนด
หากต้องการใช้มุมมองการวางซ้อนของ WebGL คุณต้องโหลดแผนที่โดยใช้รหัสแผนที่ที่เปิดใช้แผนที่เวกเตอร์ เราขอแนะนำให้เปิดใช้การเอียงและการหมุนเมื่อสร้างรหัสแผนที่ เพื่อให้ควบคุมกล้อง 3 มิติได้อย่างเต็มที่ ดูรายละเอียดได้ที่ภาพรวม
เพิ่มมุมมองการวางซ้อนของ 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);
ฮุกวงจร
มุมมองการวางซ้อนของ WebGL มีชุดฮุกที่เรียกใช้ในเวลาต่างๆ ในวงจรของบริบทการแสดงภาพ WebGL ของแผนที่ฐานแบบเวกเตอร์ ฮุกวงจรเหล่านี้เป็นตำแหน่งที่คุณตั้งค่า วาด และลบทุกอย่างที่ต้องการแสดงผลในการวางซ้อน
- ระบบจะเรียกใช้
onAdd()เมื่อสร้างการวางซ้อน ใช้ฟังก์ชันนี้เพื่อดึงหรือสร้างโครงสร้างข้อมูลระดับกลางก่อนที่จะวาดการวางซ้อน ซึ่งไม่จำเป็นต้องเข้าถึงบริบทการแสดงภาพ WebGL ทันที - ระบบจะเรียกใช้
onContextRestored({gl})เมื่อบริบทการแสดงภาพพร้อมใช้งาน ใช้ฟังก์ชันนี้เพื่อเริ่มต้นหรือผูกสถานะ WebGL เช่น Shader, ออบเจ็กต์บัฟเฟอร์ GL และอื่นๆonContextRestored()จะใช้อินสแตนซ์WebGLStateOptionsซึ่งมีฟิลด์เดียว ดังนี้glคือแฮนเดิลของWebGLRenderingContextที่แผนที่ฐานใช้
onDraw({gl, transformer})จะแสดงผลฉากบนแผนที่ฐาน พารามิเตอร์สำหรับonDraw()คือออบเจ็กต์WebGLDrawOptionsซึ่งมี 2 ฟิลด์ ดังนี้glคือแฮนเดิลของWebGLRenderingContextที่แผนที่ฐานใช้transformerมีฟังก์ชันตัวช่วยในการเปลี่ยนจากพิกัดแผนที่เป็นเมทริกซ์การฉายภาพมุมมองโมเดล ซึ่งใช้เพื่อแปลพิกัดแผนที่เป็นพื้นที่โลก พื้นที่กล้อง และพื้นที่หน้าจอได้
- ระบบจะเรียกใช้
onContextLost()เมื่อบริบทการแสดงภาพสูญหายไม่ว่าด้วยเหตุผลใดก็ตาม และเป็นตำแหน่งที่คุณควรล้างสถานะ GL ที่มีอยู่ก่อนหน้านี้ เนื่องจากไม่จำเป็นอีกต่อไป onStateUpdate({gl})จะอัปเดตสถานะ GL นอกลูปการแสดงผล และจะเรียกใช้เมื่อมีการเรียกใช้requestStateUpdateฟังก์ชันนี้จะใช้อินสแตนซ์WebGLStateOptionsซึ่งมีฟิลด์เดียว ดังนี้glคือแฮนเดิลของWebGLRenderingContextที่แผนที่ฐานใช้
- ระบบจะเรียกใช้
onRemove()เมื่อนำการวางซ้อนออกจากแผนที่ด้วยWebGLOverlayView.setMap(null)และเป็นตำแหน่งที่คุณควรนำออบเจ็กต์ระดับกลางทั้งหมดออก
ตัวอย่างเช่น การใช้งานพื้นฐานของฮุกวงจรทั้งหมดมีดังนี้
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 จะจัดการในฮุก onDraw() ตัวอย่างเช่น Three.js มีฟังก์ชันตัวช่วยที่ล้างการเปลี่ยนแปลงสถานะ GL ดังนี้
webglOverlayView.onDraw = ({gl, transformer}) => {
// Specify an object to render.
renderer.render(scene, camera);
renderer.resetState();
}
หากแผนที่หรือออบเจ็กต์แสดงผลไม่สำเร็จ อาจเป็นไปได้ว่าสถานะ GL ยังไม่ได้รีเซ็ต
การเปลี่ยนพิกัด
ตำแหน่งของออบเจ็กต์บนแผนที่เวกเตอร์จะระบุโดยการระบุพิกัดละติจูดและลองจิจูด รวมถึงระดับความสูง อย่างไรก็ตาม กราฟิก 3 มิติจะระบุในพื้นที่โลก พื้นที่กล้อง หรือพื้นที่หน้าจอ
มุมมองการวางซ้อนของ WebGL มีฟังก์ชันตัวช่วย
coordinateTransformer.fromLatLngAltitude(latLngAltitude, rotationArr,
scalarArr) ในฮุก onDraw() ซึ่งใช้พิกัดแผนที่เพื่อเปลี่ยนเป็นพื้นที่ที่ใช้กันโดยทั่วไปเหล่านี้ได้ง่ายขึ้น
โดยฟังก์ชันนี้จะใช้ข้อมูลต่อไปนี้และแสดงผล Float64Array
latLngAltitude: พิกัดละติจูด/ลองจิจูด/ระดับความสูงเป็นLatLngAltitudeหรือLatLngAltitudeLiteralrotationArr: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 แบบโอเพนซอร์สยอดนิยม เพื่อวางออบเจ็กต์ 3 มิติบนแผนที่ หากต้องการดูคำแนะนำแบบทีละขั้นเกี่ยวกับการใช้มุมมองการวางซ้อนของ WebGL เพื่อสร้างตัวอย่างที่คุณเห็น ทำงานที่ด้านบนของหน้านี้ ให้ลองใช้ Codelab การสร้างประสบการณ์การใช้งานแผนที่ที่เร่งความเร็วด้วย 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);