Режим наложения в WebGL

Посмотреть образец

С помощью WebGL Overlay View вы можете добавлять контент на свои карты напрямую с помощью WebGL или популярных графических библиотек, таких как Three.js. Просмотр наложения WebGL обеспечивает прямой доступ к тому же контексту рендеринга WebGL, который платформа Google Maps использует для рендеринга векторной базовой карты. Такое использование общего контекста рендеринга обеспечивает такие преимущества, как перекрытие глубины с геометрией трехмерного здания и возможность синхронизации 2D/3D-контента с рендерингом базовой карты. Объекты, отображаемые с помощью режима наложения WebGL, также можно привязать к координатам широты и долготы, поэтому они перемещаются при перетаскивании, масштабировании, панорамировании или наклоне карты.

Требования

Чтобы использовать режим наложения WebGL, необходимо загрузить карту, используя идентификатор карты, с включенной векторной картой. Мы настоятельно рекомендуем включить наклон и вращение при создании идентификатора карты, чтобы обеспечить полное управление 3D-камерой. Подробности смотрите в обзоре .

Добавить вид наложения 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 , который имеет два поля:
    • 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 не было сброшено.

Координатные преобразования

Положение объекта на векторной карте указывается путем указания комбинации координат широты и долготы, а также высоты. Однако трехмерная графика определяется в мировом пространстве, пространстве камеры или пространстве экрана. Чтобы упростить преобразование координат карты в эти наиболее часто используемые пространства, WebGL Overlay View предоставляет вспомогательную функцию 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 с открытым исходным кодом, для размещения 3D-объекта на карте. Чтобы получить полное пошаговое руководство по использованию представления наложения 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);