มุม���องการวางซ้อนของ 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);