Virtual reality hadir di web

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

Joe Medley
Joe Medley

Pengalaman imersif hadir di web pada Chrome 79. WebXR Device API menghadirkan virtual reality, sementara dukungan untuk augmented reality hadir di Chrome 81. Meskipun update pada GamePad API memperluas penggunaan kontrol tingkat lanjut ke VR. Browser lain akan segera mendukung spesifikasi ini, termasuk Firefox Reality, Oculus Browser, Edge, dan browser Helio Magic Leap.

Artikel ini memulai serangkaian artikel tentang web imersif. Bagian ini membahas cara menyiapkan aplikasi WebXR dasar serta cara masuk dan keluar dari sesi XR. Artikel selanjutnya akan membahas loop frame (tulang punggung pengalaman WebXR), spesifikasi augmented reality, dan WebXR Hit Test API, cara mendeteksi permukaan dalam sesi AR. Kecuali dinyatakan lain, semua yang saya bahas dalam artikel ini dan artikel berikutnya berlaku sama untuk AR dan VR.

Apa itu web imersif?

Meskipun kami menggunakan dua istilah untuk mendeskripsikan pengalaman imersif—augmented reality dan virtual reality—banyak orang menganggapnya sebagai spektrum dari realitas lengkap hingga virtual sepenuhnya, dengan tingkat imersi di antaranya. 'X' dalam XR 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 imersif sepenuhnya.
Spektrum pengalaman imersif

Contoh pengalaman imersif meliputi:

  • Game
  • Video 360°
  • Video 2D (atau 3D) tradisional yang disajikan dalam lingkungan imersif
  • Membeli rumah
  • Melihat produk di rumah Anda sebelum Anda 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 informasi yang lebih mendalam daripada yang telah saya berikan, lihat contoh WebXR dari Immersive Web Working Group atau materi referensi MDN yang terus bertambah. Jika Anda sudah terbiasa dengan versi awal WebXR Device API, Anda harus membaca sekilas semua materi ini. Ada perubahan.

Kode dalam artikel ini didasarkan pada contoh dasar Immersive Web Working Group (demo, sumber), tetapi diedit agar lebih jelas dan sederhana.

Bagian dari pembuatan spesifikasi WebXR adalah melengkapi langkah-langkah keamanan dan privasi untuk melindungi pengguna. Oleh karena itu, implementasi harus mematuhi persyaratan tertentu. Halaman web atau aplikasi harus aktif dan fokus sebelum dapat meminta hal sensitif apa pun dari penonton. 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 lakukan panggilan ke XRSystem.isSessionSupported(). Perlu diketahui bahwa di Chrome versi 79 dan 80, objek XRSystem disebut XR.

Dalam contoh di bawah, saya 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 dalam artikel berikutnya.

Setelah mengetahui bahwa sesi virtual reality didukung, saya mengaktifkan tombol yang memungkinkan saya mendapatkan 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. Objek 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 perlu memulai dan masuk ke sesi tersebut. Namun sebelumnya, 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 adegan. Harus berupa WebGLRenderingContext atau WebGL2RenderingContext yang kompatibel dengan XR. Semua gambar dibuat menggunakan framework berbasis WebGL seperti Three.js.

Setelah memiliki tempat untuk menggambar, saya memerlukan sumber konten untuk digambar di sana. Untuk itu, saya membuat instance XRWebGLLayer. Saya mengaitkannya dengan kanvas dengan memanggil XRSession.updateRenderState().

Setelah bergabung dalam sesi, saya memerlukan cara untuk menentukan lokasi objek dalam virtual reality. Saya memerlukan ruang referensi. Ruang referensi 'local-floor' adalah ruang dengan titik asal yang terletak di dekat penonton 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 memerlukannya 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 dari presentasi konten virtual, yang dilakukan dalam loop frame.

Menjalankan loop frame

Loop frame adalah loop tanpa batas yang dikontrol oleh agen pengguna, yang kontennya berulang kali digambar 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 30 frame per detik. Kode Anda tidak boleh mengasumsikan frame rate 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:
    1. Telepon XRSession.requestAnimationFrame() lagi.
    2. Dapatkan pose penonton.
    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 selanjutnya dalam artikel ini menjelaskan langkah 1 dan sebagian langkah 2, yaitu menyiapkan dan memanggil XRFrameRequestCallback. Item yang tersisa dari langkah 2 dibahas di bagian II.

XRFrameRequestCallback

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

Sebelum melakukan hal lain, saya akan meminta frame animasi berikutnya. Seperti yang dinyatakan sebelumnya, pengaturan waktu frame ditentukan oleh agen pengguna berdasarkan hardware yang mendasarinya. Meminta frame berikutnya terlebih dahulu 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 pembahasan untuk bagian II. Sebelum membuka halaman tersebut, izinkan saya menunjukkan cara mengakhiri sesi.

Mengakhiri sesi

Sesi imersif dapat berakhir karena beberapa alasan, termasuk diakhiri oleh kode Anda sendiri melalui panggilan ke XRSession.end(). Penyebab lainnya termasuk headset yang terputus atau aplikasi lain yang mengambil kontrol headset. Itulah sebabnya aplikasi yang berperilaku baik harus memantau peristiwa end. Jika hal ini terjadi, batalkan sesi dan objek render terkaitnya. Sesi imersif yang telah berakhir tidak dapat dilanjutkan. Untuk masuk kembali ke 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 butuhkan untuk menulis aplikasi Web XR atau AR. Semoga, saya telah memberikan cukup banyak informasi untuk membantu Anda memahami kode sendiri, dan cukup banyak informasi untuk mulai bereksperimen. Dalam artikel berikutnya, saya akan menjelaskan loop frame, yaitu tempat konten digambar ke layar.