Chế độ xem lớp phủ WebGL

Xem mẫu

Với Chế độ xem lớp phủ WebGL, bạn có thể thêm trực tiếp nội dung vào bản đồ của mình bằng cách sử dụng WebGL, hoặc các thư viện Đồ họa phổ biến như Three.js. Chế độ xem lớp phủ WebGL cung cấp quyền truy cập trực tiếp vào cùng một bối cảnh kết xuất WebGL mà Nền tảng Google Maps sử dụng để hiển thị bản đồ cơ sở vectơ. Việc sử dụng ngữ cảnh kết xuất chia sẻ này mang lại các lợi ích như che khuất chiều sâu với hình học toà nhà 3D và khả năng đồng bộ hoá nội dung 2D/3D với tính năng kết xuất bản đồ cơ sở. Các đối tượng được kết xuất bằng Chế độ xem lớp phủ WebGL cũng có thể được liên kết với toạ độ vĩ độ/kinh độ, vì vậy, các đối tượng sẽ di chuyển khi bạn kéo, thu phóng, xoay hoặc nghiêng bản đồ.

Yêu cầu

Để sử dụng Chế độ xem lớp phủ WebGL, bạn phải tải bản đồ bằng cách sử dụng ID bản đồ với bản đồ vectơ đã bật. Bạn nên bật tính năng nghiêng và xoay khi tạo mã bản đồ để cho phép điều khiển hoàn toàn máy ảnh 3D. Xem tổng quan để biết chi tiết.

Thêm chế độ xem lớp phủ WebGL

Để thêm lớp phủ vào bản đồ, hãy triển khai google.maps.WebGLOverlayView, sau đó truyền vào thực thể bản đồ này bằng cách sử dụng 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);

Hook vòng đời

Chế độ xem lớp phủ WebGL cung cấp một tập hợp hook được gọi tại các thời điểm khác nhau trong vòng đời của bối cảnh kết xuất WebGL của bản đồ cơ sở vectơ. Các hook vòng đời này là nơi bạn thiết lập, vẽ và chia nhỏ bất kỳ nội dung nào bạn muốn hiển thị trong lớp phủ.

  • onAdd() được gọi khi tạo lớp phủ. Hãy sử dụng đối tượng này để tìm nạp hoặc tạo các cấu trúc dữ liệu trung gian trước khi vẽ lớp phủ mà không yêu cầu quyền truy cập ngay vào ngữ cảnh kết xuất WebGL.
  • onContextRestored({gl}) được gọi sau khi ngữ cảnh kết xuất có sẵn. Hãy sử dụng thuộc tính này để khởi động hoặc liên kết bất kỳ trạng thái WebGL nào, chẳng hạn như chương trình đổ bóng, đối tượng bộ đệm GL, v.v. onContextRestored() lấy thực thể WebGLStateOptions, có một trường duy nhất:
    • gl là một đối tượng điều khiển cho WebGLRenderingContext mà bản đồ cơ sở sử dụng.
  • onDraw({gl, transformer}) kết xuất cảnh trên bản đồ cơ sở. Tham số cho onDraw() là một đối tượng WebGLDrawOptions, có hai trường:
    • gl là một đối tượng điều khiển cho WebGLRenderingContext mà bản đồ cơ sở sử dụng.
    • transformer cung cấp các hàm trợ giúp để chuyển đổi từ toạ độ bản đồ sang ma trận phép chiếu mô hình-hình-ảnh. Ma trận này có thể được dùng để diễn giải toạ độ bản đồ sang không gian thế giới, không gian máy ảnh và không gian màn hình.
  • onContextLost() được gọi khi ngữ cảnh kết xuất bị mất vì bất kỳ lý do gì. Đây là nơi bạn nên dọn dẹp mọi trạng thái GL có sẵn từ trước, vì trạng thái này không còn cần thiết nữa.
  • onStateUpdate({gl}) cập nhật trạng thái GL bên ngoài vòng lặp kết xuất và được gọi khi requestStateUpdate được gọi. Cần có một thực thể WebGLStateOptions, có một trường duy nhất:
    • gl là một đối tượng điều khiển cho WebGLRenderingContext mà bản đồ cơ sở sử dụng.
  • onRemove() được gọi khi lớp phủ bị xoá khỏi bản đồ bằng WebGLOverlayView.setMap(null) và là nơi bạn nên xoá mọi đối tượng trung gian.

Ví dụ: sau đây là cách triển khai cơ bản của tất cả hook vòng đời:

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);

Đặt lại trạng thái GL

Chế độ xem lớp phủ WebGL hiển thị ngữ cảnh kết xuất WebGL của bản đồ cơ sở. Do đó, điều cực kỳ quan trọng là bạn phải đặt lại trạng thái GL về trạng thái ban đầu sau khi kết xuất xong đối tượng. Việc không đặt lại trạng thái GL có thể dẫn đến xung đột trạng thái GL, khiến quá trình kết xuất cả bản đồ và mọi đối tượng mà bạn chỉ định không thành công.

Việc đặt lại trạng thái GL thường được xử lý trong hook onDraw(). Ví dụ: Three.js cung cấp chức năng trợ giúp để xoá mọi thay đổi đối với trạng thái GL:

webglOverlayView.onDraw = ({gl, transformer}) => {
  // Specify an object to render.
  renderer.render(scene, camera);
  renderer.resetState();
}

Nếu bản đồ hoặc các đối tượng của bạn không kết xuất được, rất có thể trạng thái GL chưa được đặt lại.

Chuyển đổi toạ độ

Vị trí của một đối tượng trên bản đồ vectơ được chỉ định bằng cách cung cấp tổ hợp toạ độ vĩ độ và kinh độ, cũng như độ cao. Tuy nhiên, đồ hoạ 3D được chỉ định trong không gian thế giới, không gian máy ảnh hoặc không gian màn hình. Để giúp việc chuyển đổi toạ độ bản đồ sang các không gian thường dùng hơn này trở nên dễ dàng hơn, Chế độ xem lớp phủ WebGL cung cấp hàm trợ giúp coordinateTransformer.fromLatLngAltitude(latLngAltitude, rotationArr, scalarArr) trong hook onDraw() để nhận những giá trị sau và trả về một Float64Array:

  • latLngAltitude: Vĩ độ/kinh độ/độ cao ở dạng LatLngAltitude hoặc LatLngAltitudeLiteral.
  • rotationArr: Float32Array góc xoay euler được chỉ định bằng độ.
  • scalarArr: Float32Array của các đại lượng vô hướng để áp dụng cho trục chính.

Ví dụ: đoạn mã sau đây sử dụng fromLatLngAltitude() để tạo ma trận chiếu máy ảnh trong 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);

Ví dụ:

Sau đây là ví dụ đơn giản về cách sử dụng Three.js, một thư viện WebGL nguồn mở, phổ biến để đặt đối tượng 3D trên bản đồ. Để có hướng dẫn đầy đủ về cách sử dụng Chế độ xem lớp phủ WebGL để xây dựng ví dụ mà bạn thấy ở đầu trang này, hãy thử Lớp học lập trình về cách xây dựng trải nghiệm bản đồ được tăng tốc bằng 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);