Virtual reality hadir di web

Beberapa dasar untuk mempersiapkan Anda menghadapi spektrum pengalaman imersif: virtual reality, augmented reality, dan lainnya.

Joe Medley
Joe Medley

Pengalaman imersif hadir di web pada Chrome 79. WebXR Device API menghadirkan VR, sementara dukungan untuk AR hadir di Chrome 81. Sementara update pada GamePad API memperluas penggunaan kontrol lanjutan ke VR. Browser lain akan segera mendukung spesifikasi ini, termasuk Firefox Reality, Oculus Browser, Edge, dan browser Helio Magic Leap, di antara lainnya.

Artikel ini memulai rangkaian tentang web imersif. Bagian ini membahas cara menyiapkan aplikasi WebXR dasar serta memasuki dan keluar dari sesi XR. Artikel berikutnya akan membahas loop frame (pekerja keras pengalaman WebXR), detail augmented reality, dan WebXR Hit Test API, yaitu cara mendeteksi platform dalam sesi AR. Kecuali jika dinyatakan lain, semua yang saya bahas dalam artikel ini dan artikel berikutnya berlaku sama untuk AR dan VR.

Apa itu web imersif?

Meskipun kita menggunakan dua istilah untuk mendeskripsikan pengalaman imersif—augmented reality dan virtual reality—banyak orang menganggapnya sebagai spektrum dari realitas lengkap hingga sepenuhnya virtual, dengan tingkat imersi di antaranya. 'X' dalam VR dimaksudkan untuk mencerminkan pemikiran tersebut dengan menjadi semacam variabel aljabar yang mewakili apa pun dalam spektrum pengalaman imersif.

Grafik yang menggambarkan spektrum pengalaman visual dari realitas lengkap hingga sepenuhnya imersif.
Spektrum pengalaman imersif

Contoh pengalaman imersif meliputi:

  • Game
  • Video 360°
  • Video 2D (atau 3D) tradisional yang disajikan dalam lingkungan imersif
  • Pembelian rumah
  • Melihat produk di rumah Anda sebelum membelinya
  • Seni imersif
  • Sesuatu yang keren yang belum terpikirkan oleh siapa pun

Konsep dan penggunaan

Saya akan menjelaskan beberapa dasar penggunaan WebXR Device API. Jika Anda memerlukan penjelasan lebih mendalam dari yang telah saya berikan, lihat contoh WebXR dari Immersive Web Working Group atau materi referensi yang terus berkembang di MDN. Jika sudah terbiasa dengan versi awal WebXR Device API, Anda harus melihat sekilas semua materi ini. Ada perubahan.

Kode dalam artikel ini didasarkan pada contoh dasar Immersive Web Working Group (demo, source), tetapi diedit untuk kejelasan dan kesederhanaan.

Bagian dari pembuatan spesifikasi WebXR adalah memperjelas langkah keamanan dan privasi untuk melindungi pengguna. Oleh karena itu, implementasi harus mematuhi persyaratan tertentu. Halaman web atau aplikasi harus aktif dan difokuskan sebelum dapat meminta informasi sensitif apa pun dari pelihat. Halaman web atau aplikasi harus ditayangkan melalui HTTPS. API itu sendiri dirancang untuk melindungi informasi yang diperoleh dari sensor dan kamera, yang diperlukan agar dapat berfungsi.

Meminta sesi

Memasuki sesi XR memerlukan gestur pengguna. Untuk mendapatkannya, gunakan deteksi fitur untuk menguji XRSystem (melalui navigator.xr) dan melakukan panggilan ke XRSystem.isSessionSupported(). Perhatikan bahwa di Chrome versi 79 dan 80, objek XRSystem disebut XR.

Pada contoh di bawah, saya telah menunjukkan bahwa saya ingin sesi virtual reality dengan jenis sesi 'immersive-vr'. Jenis sesi lainnya adalah 'immersive-ar' dan 'inline'. Sesi inline digunakan untuk menampilkan konten dalam HTML dan terutama digunakan untuk konten teaser. Contoh Sesi AR Imersif menunjukkan hal ini. Saya akan menjelaskannya di artikel berikutnya.

Setelah mengetahui bahwa sesi virtual reality didukung, saya mengaktifkan tombol yang memungkinkan saya memperoleh gestur pengguna.

if (navigator.xr) {
  const supported = await navigator.xr.isSessionSupported('immersive-vr');
  if (supported) {
    xrButton.addEventListener('click', onButtonClicked);
    xrButton.textContent = 'Enter VR';
    xrButton.enabled = supported; // supported is Boolean
  }
}

Setelah mengaktifkan tombol, saya menunggu peristiwa klik, lalu meminta sesi.

let xrSession = null;
function onButtonClicked() {
  if (!xrSession) {
    navigator.xr.requestSession('immersive-vr')
    .then((session) => {
      xrSession = session;
      xrButton.textContent = 'Exit XR';
      onSessionStarted(xrSession);
    });
  } else {
    xrSession.end();
  }
}

Perhatikan hierarki objek dalam kode ini. Pengujian ini berpindah dari navigator ke xr ke instance XRSession. Pada versi awal API, skrip harus meminta perangkat sebelum meminta sesi. Sekarang, perangkat diperoleh secara implisit.

Masuk ke sesi

Setelah mendapatkan sesi, saya harus memulai dan memasukinya. Namun, pertama-tama, saya perlu menyiapkan beberapa hal. Sesi memerlukan pengendali peristiwa onend agar aplikasi atau halaman web dapat direset saat pengguna keluar.

Saya juga memerlukan elemen <canvas> untuk menggambar scene saya. Konteks ini harus berupa WebGLRenderingContext atau WebGL2RenderingContext yang kompatibel dengan XR. Semua gambar dilakukan menggunakan keduanya atau framework berbasis WebGL seperti Three.js.

Sekarang setelah saya memiliki tempat untuk menggambar, saya perlu sumber konten untuk menggambar di atasnya. Untuk itu, saya membuat instance XRWebGLLayer. Saya mengaitkannya dengan kanvas dengan memanggil XRSession.updateRenderState().

Setelah berada dalam sesi, saya memerlukan cara untuk menentukan lokasi berbagai hal dalam virtual reality. Saya akan membutuhkan ruang referensi. Ruang referensi 'local-floor' adalah ruang tempat asal berada di dekat penampil dan sumbu y adalah 0 di tingkat lantai dan tidak diharapkan untuk bergerak. Ada jenis ruang referensi lainnya, tetapi itu adalah topik yang lebih rumit daripada yang dapat saya bahas di sini. Saya menyimpan ruang referensi ke variabel karena saya akan membutuhkannya saat menggambar ke layar.

function onSessionStarted(xrSession) {
  xrSession.addEventListener('end', onSessionEnded);

  let canvas = document.createElement('canvas');
  webGLRenContext = canvas.getContext('webgl', { xrCompatible: true });

  xrSession.updateRenderState({
    baseLayer: new XRWebGLLayer(xrSession, webGLRenContext)
  });

  xrSession.requestReferenceSpace('local-floor')
  .then((refSpace) => {
    xrRefSpace = refSpace;
    xrSession.requestAnimationFrame(onXRFrame);
  });
}

Setelah mendapatkan ruang referensi, saya memanggil XRSession.requestAnimationFrame(). Ini adalah awal presentasi konten virtual, yang dilakukan dalam loop bingkai.

Menjalankan loop frame

Frame loop adalah loop tak terbatas yang dikontrol oleh agen pengguna, tempat konten digambar berulang kali ke layar. Konten digambar dalam blok terpisah yang disebut frame. Urutan frame menciptakan ilusi gerakan. Untuk aplikasi VR, frame per detik dapat berkisar antara 60 hingga 144. AR untuk Android berjalan pada kecepatan 30 frame per detik. Kode Anda tidak boleh mengasumsikan kecepatan frame tertentu.

Proses dasar untuk loop frame adalah:

  1. Hubungi XRSession.requestAnimationFrame(). Sebagai respons, agen pengguna memanggil XRFrameRequestCallback, yang ditentukan oleh Anda.
  2. Di dalam fungsi callback Anda:
    1. Telepon XRSession.requestAnimationFrame() lagi.
    2. Dapatkan pose penampil.
    3. Teruskan ('bind') WebGLFramebuffer dari XRWebGLLayer ke WebGLRenderingContext.
    4. Lakukan iterasi pada setiap objek XRView, ambil XRViewport-nya dari XRWebGLLayer, lalu teruskan ke WebGLRenderingContext.
    5. Menggambar sesuatu ke framebuffer.

Bagian lain dari artikel ini menjelaskan langkah 1 dan bagian dari langkah 2, menyiapkan dan memanggil XRFrameRequestCallback. Item lainnya dari langkah 2 akan dibahas di bagian II.

XRFrameRequestCallback

XRFrameRequestCallback ditentukan oleh Anda. Metode ini memerlukan dua parameter: DOMHighResTimeStamp dan instance XRFrame. Objek XRFrame memberikan informasi yang diperlukan untuk merender satu frame ke layar. Argumen DOMHighResTimeStamp adalah untuk penggunaan mendatang.

Sebelum melakukan hal lain, saya akan meminta frame animasi berikutnya. Seperti yang dinyatakan sebelumnya, waktu render frame ditentukan oleh agen pengguna berdasarkan hardware yang mendasarinya. Meminta frame berikutnya terlebih dahulu akan memastikan bahwa loop frame berlanjut jika terjadi error selama callback.

function onXRFrame(hrTime, xrFrame) {
  let xrSession = xrFrame.session;
  xrSession.requestAnimationFrame(onXRFrame);
  // Render a frame.
}

Pada tahap ini, saatnya menggambar sesuatu untuk penonton. Itu adalah diskusi untuk bagian II. Sebelum melanjutkan, izinkan saya menunjukkan cara mengakhiri sesi.

Akhiri sesi

Sesi imersif dapat berakhir karena beberapa alasan, termasuk berakhir oleh kode Anda sendiri melalui panggilan ke XRSession.end(). Penyebab lainnya termasuk koneksi headset terputus atau aplikasi lain yang mengendalikannya. Itulah sebabnya aplikasi yang berperilaku baik harus memantau peristiwa end. Jika terjadi, hapus sesi dan objek render terkait. Sesi imersif yang telah berakhir tidak dapat dilanjutkan. Untuk memasuki kembali pengalaman imersif, aplikasi saya perlu memulai sesi baru.

Ingat dari Memasuki sesi bahwa selama penyiapan, saya menambahkan pengendali peristiwa onend.

function onSessionStarted(xrSession) {
  xrSession.addEventListener('end', onSessionEnded);
  // More setup…
}

Di dalam pengendali peristiwa, pulihkan status aplikasi sebelum pengguna memasuki sesi.

function onSessionEnded(event) {
  xrSession = null;
  xrButton.textContent = 'Enter VR';
}

Kesimpulan

Saya belum menjelaskan semua yang Anda perlukan untuk menulis aplikasi Web XR atau AR. Mudah-mudahan, saya sudah memberi Anda cukup untuk mulai memahami kode itu sendiri, dan cukup untuk mulai bereksperimen. Dalam artikel berikutnya, saya akan menjelaskan loop bingkai, tempat konten digambar ke layar.

Foto oleh JESHOOTS.COM di Unsplash