ด้วยมุมมองการวางซ้อน 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 เช่น ตัวปรับแสงเงา ออบเจ็กต์บัฟเฟอร์ 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
หรือ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 แบบโอเพนซอร์สที่เป็นที่นิยมในการวางวัตถุ 3 มิติบนแผนที่ สำหรับขั้นตอนทั้งหมดในการใช้มุมมองการวางซ้อน WebGL เพื่อสร้างตัวอย่างที่คุณเห็นอยู่ที่ด้านบนของหน้านี้ ให้ลองใช้โค้ดแล็บการสร้างแผนที่แบบเร่งความเร็วด้วย 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);