نمای همپوشانی WebGL

مشاهده نمونه

با استفاده از WebGL Overlay View می‌توانید مستقیماً با استفاده از WebGL یا کتابخانه‌های گرافیکی محبوب مانند Three.js به نقشه‌های خود محتوا اضافه کنید. WebGL Overlay View دسترسی مستقیم به همان زمینه رندر WebGL را که پلتفرم Google Maps برای رندر نقشه پایه برداری استفاده می‌کند، فراهم می‌کند. این استفاده از یک زمینه رندر مشترک، مزایایی مانند انسداد عمق با هندسه ساختمان سه‌بعدی و امکان همگام‌سازی محتوای دوبعدی/سه‌بعدی با رندر نقشه پایه را فراهم می‌کند. اشیاء رندر شده با WebGL Overlay View همچنین می‌توانند به مختصات عرض جغرافیایی/طول جغرافیایی گره خورده باشند، بنابراین هنگام کشیدن، بزرگنمایی، حرکت افقی یا عمودی نقشه، حرکت می‌کنند.

الزامات

برای استفاده از نمای همپوشانی WebGL، باید نقشه را با استفاده از شناسه نقشه که نقشه برداری در آن فعال است، بارگذاری کنید. اکیداً توصیه می‌کنیم هنگام ایجاد شناسه نقشه، شیب و چرخش را فعال کنید تا امکان کنترل کامل دوربین سه‌بعدی فراهم شود. برای جزئیات بیشتر به نمای کلی مراجعه کنید .

نمای روکش 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);

قلاب‌های چرخه عمر

نمای پوششی وب‌جی‌ال مجموعه‌ای از قلاب‌ها را ارائه می‌دهد که در زمان‌های مختلف در چرخه حیات زمینه رندرینگ وب‌جی‌ال از نقشه پایه برداری فراخوانی می‌شوند. این قلاب‌های چرخه حیات جایی هستند که شما هر چیزی را که می‌خواهید در پوشش رندر شود، تنظیم، ترسیم و حذف می‌کنید.

  • onAdd() هنگام ایجاد overlay فراخوانی می‌شود. از آن برای دریافت یا ایجاد ساختارهای داده میانی قبل از ترسیم overlay که نیازی به دسترسی فوری به زمینه رندر WebGL ندارند، استفاده کنید.
  • onContextRestored({gl}) زمانی فراخوانی می‌شود که زمینه رندرینگ در دسترس باشد. از آن برای مقداردهی اولیه یا اتصال هر حالت WebGL مانند shaderها، اشیاء بافر 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، برای قرار دادن یک شیء سه‌بعدی روی نقشه آمده است. برای مشاهده راهنمای کامل استفاده از WebGL Overlay View برای ساخت مثالی که در بالای این صفحه مشاهده می‌کنید، می‌توانید از codelab Building WebGL-accelerated Map Experiences استفاده کنید.

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