มุมมองการวางซ้อน 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
หรือ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 เพื่อสร้างตัวอย่างที่คุณเห็นแสดงอยู่ที่ด้านบนของหน้านี้ได้จาก 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);