มุมมองการวางซ้อนของ WebGL

ดูตัวอย่าง

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