Selamat datang di web imersif

Web imersif berarti pengalaman dunia virtual yang dihosting melalui browser. Seluruh pengalaman virtual reality ini muncul di browser atau di headset yang mendukung VR.

Joe Medley
Joe Medley

Web imersif berarti pengalaman dunia virtual yang dihosting melalui browser. Hal ini mencakup seluruh pengalaman virtual reality (VR) yang ditampilkan di browser atau di headset yang mendukung VR seperti Google's Daydream, Oculus Rift, Samsung Gear VR, HTC Vive, dan Windows Mixed Reality Headsets, serta pengalaman augmented reality yang dikembangkan untuk perangkat seluler yang mendukung AR.

Meskipun kita menggunakan dua istilah untuk mendeskripsikan pengalaman imersif, keduanya harus dianggap sebagai spektrum dari realitas lengkap hingga lingkungan VR yang sepenuhnya imersif, dengan berbagai tingkat AR di antaranya.

Contoh pengalaman imersif meliputi:

  • Video 360° imersif
  • Video 2D (atau 3D) tradisional yang disajikan dalam lingkungan imersif
  • Visualisasi data
  • Belanja di rumah
  • Seni
  • Sesuatu yang keren yang belum terpikirkan oleh siapa pun

Bagaimana saya bisa ke sana?

Web imersif telah tersedia selama hampir setahun dalam bentuk embrio. Hal ini dilakukan melalui WebVR 1.1 API, yang telah tersedia dalam uji coba origin sejak Chrome 62. API tersebut juga didukung oleh Firefox dan Edge serta polyfill untuk Safari.

Namun, sekarang saatnya untuk beralih.

Uji coba origin berakhir pada 24 Juli 2018, dan spesifikasinya telah diganti dengan WebXR Device API dan uji coba origin baru.

Apa yang terjadi dengan WebVR 1.1?

Kami belajar banyak dari WebVR 1.1, tetapi seiring waktu, makin jelas bahwa beberapa perubahan besar diperlukan untuk mendukung jenis aplikasi yang ingin di-build oleh developer. Daftar lengkap pelajaran yang telah dipelajari terlalu panjang untuk dibahas di sini, tetapi mencakup masalah seperti API yang terikat secara eksplisit dengan thread JavaScript utama, terlalu banyak peluang bagi developer untuk menyiapkan konfigurasi yang jelas-jelas salah , dan penggunaan umum seperti jendela ajaib sebagai efek samping, bukan fitur yang disengaja. (Jendela ajaib adalah teknik untuk melihat konten imersif tanpa headset, dengan aplikasi merender satu tampilan berdasarkan sensor orientasi perangkat.)

Desain baru ini memfasilitasi penerapan yang lebih sederhana dan peningkatan performa yang besar. Pada saat yang sama, AR dan kasus penggunaan lainnya mulai bermunculan dan menjadi penting bahwa API dapat diperluas untuk mendukung penggunaan di masa mendatang.

WebXR Device API dirancang dan diberi nama dengan mempertimbangkan kasus penggunaan yang diperluas ini dan memberikan jalur yang lebih baik ke depannya. Implementasi WebVR telah berkomitmen untuk bermigrasi ke WebXR Device API.

Apa yang dimaksud dengan WebXR Device API?

Seperti spesifikasi WebVR sebelumnya, WebXR Device API adalah produk dari Immersive Web Community Group yang memiliki kontributor dari Google, Microsoft, Mozilla, dan lainnya. 'X dalam XR dimaksudkan sebagai semacam variabel aljabar yang mewakili apa pun dalam spektrum pengalaman imersif. Versi ini tersedia dalam uji coba origin yang disebutkan sebelumnya serta melalui polyfill.

Saat artikel ini pertama kali dipublikasikan selama periode Chrome 67 beta, hanya kemampuan VR yang diaktifkan. Augmented reality hadir di Chrome 69. Baca tentang hal ini di Augmented reality untuk web.

Ada banyak hal lain tentang API baru ini yang tidak dapat saya bahas dalam artikel seperti ini. Saya ingin memberi Anda cukup informasi untuk mulai memahami contoh WebXR. Anda dapat menemukan informasi selengkapnya di penjelasan asli dan Panduan Pengguna Awal Web Imersif kami. Saya akan memperluas yang terakhir seiring uji coba origin berlangsung. Jangan ragu untuk membuka masalah atau mengirimkan permintaan pull.

Untuk artikel ini, saya akan membahas cara memulai, menghentikan, dan menjalankan sesi XR, ditambah beberapa dasar tentang pemrosesan input.

Yang tidak akan saya bahas adalah cara menggambar konten AR/VR ke layar. WebXR Device API tidak menyediakan fitur rendering gambar. Keputusannya ada di tangan Anda. Menggambar dilakukan menggunakan WebGL API. Anda dapat melakukannya jika benar-benar ambisius. Meskipun demikian, kami merekomendasikan penggunaan kerangka kerja. Contoh web imersif menggunakan contoh yang dibuat khusus untuk demo yang disebut Cottontail. Three.js telah mendukung WebXR sejak bulan Mei. Saya belum pernah mendengar apa pun tentang A-Frame.

Memulai dan menjalankan aplikasi

Proses dasarnya adalah sebagai berikut:

  1. Meminta perangkat XR.
  2. Jika tersedia, minta sesi XR. Jika Anda ingin pengguna memasukkan ponsel ke headset, hal ini disebut sesi imersif dan memerlukan gestur pengguna untuk masuk.
  3. Gunakan sesi tersebut untuk menjalankan loop render yang menyediakan 60 frame gambar per detik. Gambarkan konten yang sesuai ke layar di setiap frame.
  4. Jalankan loop render hingga pengguna memutuskan untuk keluar.
  5. Akhiri sesi XR.

Mari kita lihat hal ini secara lebih mendetail dan sertakan beberapa kode. Anda tidak akan dapat menjalankan aplikasi dari yang akan saya tunjukkan. Namun, sekali lagi, ini hanya untuk memberikan gambaran.

Meminta perangkat XR

Di sini, Anda akan mengenali kode deteksi fitur standar. Anda dapat menggabungkannya dalam fungsi yang disebut seperti checkForXR().

Jika tidak menggunakan sesi imersif, Anda dapat melewati iklan fungsi dan mendapatkan gestur pengguna, lalu langsung meminta sesi. Sesi imersif adalah sesi yang memerlukan headset. Sesi non-imersif hanya menampilkan konten di layar perangkat. Yang pertama adalah yang paling banyak dipikirkan orang saat Anda merujuk ke virtual reality atau augmented reality. Yang terakhir terkadang disebut 'jendela ajaib'.

if (navigator.xr) {
    navigator.xr.requestDevice()
    .then(xrDevice => {
    // Advertise the AR/VR functionality to get a user gesture.
    })
    .catch(err => {
    if (err.name === 'NotFoundError') {
        // No XRDevices available.
        console.error('No XR devices available:', err);
    } else {
        // An error occurred while requesting an XRDevice.
        console.error('Requesting XR device failed:', err);
    }
    })
} else{
    console.log("This browser does not support the WebXR API.");
}

Meminta sesi XR

Setelah memiliki perangkat dan gestur pengguna, sekarang saatnya mendapatkan sesi. Untuk membuat sesi, browser memerlukan kanvas tempat menggambar.

xrPresentationContext = htmlCanvasElement.getContext('xrpresent');
let sessionOptions = {
    // The immersive option is optional for non-immersive sessions; the value
    //   defaults to false.
    immersive: false,
    outputContext: xrPresentationContext
}
xrDevice.requestSession(sessionOptions)
.then(xrSession => {
    // Use a WebGL context as a base layer.
    xrSession.baseLayer = new XRWebGLLayer(session, gl);
    // Start the render loop
})

Menjalankan loop render

Kode untuk langkah ini perlu sedikit diurai. Untuk mengurainya, saya akan memberi tahu Anda beberapa kata. Jika Anda ingin melihat kode akhir, lanjutkan untuk melihat sekilas, lalu kembali untuk mendapatkan penjelasan lengkap. Ada banyak hal yang mungkin tidak dapat Anda simpulkan.

Proses dasar untuk loop render adalah sebagai berikut:

  1. Minta frame animasi.
  2. Mengkueri posisi perangkat.
  3. Gambar konten ke posisi perangkat berdasarkan posisinya.
  4. Melakukan pekerjaan yang diperlukan untuk perangkat input.
  5. Ulangi 60 kali per detik hingga pengguna memutuskan untuk berhenti.

Meminta bingkai presentasi

Kata 'frame' memiliki beberapa arti dalam konteks Web XR. Yang pertama adalah frame of reference yang menentukan tempat asal sistem koordinat dihitung, dan apa yang terjadi pada asal tersebut saat perangkat bergerak. (Apakah tampilan tetap sama saat pengguna bergerak atau bergeser seperti yang terjadi dalam kehidupan nyata?)

Jenis frame kedua adalah frame presentasi, yang diwakili oleh objek XRFrame. Objek ini berisi informasi yang diperlukan untuk merender satu frame dari tampilan AR/VR ke perangkat. Hal ini sedikit membingungkan karena frame presentasi diambil dengan memanggil requestAnimationFrame(). Ini membuatnya kompatibel dengan window.requestAnimationFrame().

Sebelum saya memberikan ringkasan lainnya, saya akan menawarkan beberapa kode. Contoh di bawah menunjukkan cara loop render dimulai dan dikelola. Perhatikan penggunaan ganda bingkai kata. Dan perhatikan panggilan rekursif ke requestAnimationFrame(). Fungsi ini akan dipanggil 60 kali per detik.

xrSession.requestFrameOfReference('eye-level')
.then(xrFrameOfRef => {
    xrSession.requestAnimationFrame(onFrame(time, xrFrame) {
    // The time argument is for future use and not implemented at this time.
    // Process the frame.
    xrFrame.session.requestAnimationFrame(onFrame);
    }
});

Pose

Sebelum menggambar apa pun ke layar, Anda perlu mengetahui ke mana perangkat tampilan mengarah dan Anda memerlukan akses ke layar. Secara umum, posisi dan orientasi suatu benda di AR/VR disebut pose. Baik penampil maupun perangkat input memiliki pose. (Saya akan membahas perangkat input nanti.) Pose perangkat penampil dan perangkat input didefinisikan sebagai matriks 4 x 4 yang disimpan dalam Float32Array dalam urutan kolom utama. Anda mendapatkan pose penampil dengan memanggil XRFrame.getDevicePose() pada objek frame animasi saat ini. Selalu uji untuk melihat apakah Anda mendapatkan pose kembali. Jika terjadi error, Anda tidak ingin menggambar ke layar.

let pose = xrFrame.getDevicePose(xrFrameOfRef);
if (pose) {
    // Draw something to the screen.
}

Penayangan

Setelah memeriksa posenya, saatnya menggambar sesuatu. Objek yang Anda gambar disebut tampilan (XRView). Di sinilah jenis sesi menjadi penting. Tampilan diambil dari objek XRFrame sebagai array. Jika Anda berada dalam sesi non-immersive, array akan memiliki satu tampilan. Jika Anda berada dalam sesi imersif, array memiliki dua, satu untuk setiap mata.

for (let view of xrFrame.views) {
    // Draw something to the screen.
}

Ini adalah perbedaan penting antara WebXR dan sistem imersif lainnya. Meskipun tampaknya tidak ada gunanya melakukan iterasi melalui satu tampilan, tindakan ini memungkinkan Anda memiliki satu jalur rendering untuk berbagai perangkat.

Seluruh loop render

Jika menggabungkan semua ini, saya akan mendapatkan kode di bawah. Saya telah meninggalkan placeholder untuk perangkat input, yang akan saya bahas di bagian selanjutnya.

xrSession.requestFrameOfReference('eye-level')
.then(xrFrameOfRef => {
    xrSession.requestAnimationFrame(onFrame(time, xrFrame) {
    // The time argument is for future use and not implemented at this time.
    let pose = xrFrame.getDevicePose(xrFrameOfRef);
    if (pose) {
        for (let view of xrFrame.views) {
        // Draw something to the screen.
        }
    }
    // Input device code will go here.
    frame.session.requestAnimationFrame(onFrame);
    }
}

Akhiri sesi XR

Sesi XR dapat berakhir karena beberapa alasan, termasuk berakhir dengan kode Anda sendiri melalui panggilan ke XRSession.end(). Penyebab lainnya termasuk headset terputus atau aplikasi lain mengambil alih kontrolnya. Itulah sebabnya aplikasi yang berperilaku baik harus memantau peristiwa akhir dan saat terjadi, menghapus objek sesi dan perender. Sesi XR setelah berakhir tidak dapat dilanjutkan.

xrDevice.requestSession(sessionOptions)
.then(xrSession => {
    // Create a WebGL layer and initialize the render loop.
    xrSession.addEventListener('end', onSessionEnd);
});

// Restore the page to normal after immersive access has been released.
function onSessionEnd() {
    xrSession = null;

    // Ending the session stops executing callbacks passed to the XRSession's
    // requestAnimationFrame(). To continue rendering, use the window's
    // requestAnimationFrame() function.
    window.requestAnimationFrame(onDrawFrame);
}

Bagaimana cara kerja interaksi?

Seperti masa aktif aplikasi, saya hanya akan memberi Anda gambaran tentang cara berinteraksi dengan objek di AR atau VR.

WebXR Device API mengadopsi pendekatan "tunjuk dan klik" untuk input pengguna. Dengan pendekatan ini, setiap sumber input memiliki sinar pointer yang telah ditetapkan untuk menunjukkan tempat perangkat input ditunjuk dan peristiwa untuk menunjukkan kapan sesuatu dipilih. Aplikasi Anda menggambar sinar pointer dan menunjukkan tempat sinar tersebut mengarah. Saat pengguna mengklik perangkat input, peristiwa akan diaktifkan - khususnya, select, selectStart, dan selectEnd. Aplikasi Anda menentukan apa yang diklik dan merespons dengan tepat.

Perangkat input dan sinar pointer

Bagi pengguna, sinar pointer hanyalah garis tipis antara pengontrol dan apa pun yang mereka tunjuk. Namun, aplikasi Anda harus menggambarnya. Artinya, mendapatkan pose perangkat input dan menggambar garis dari lokasinya ke objek di ruang AR/VR. Prosesnya kira-kira terlihat seperti ini:

let inputSources = xrSession.getInputSources();
for (let xrInputSource of inputSources) {
    let inputPose = frame.getInputPose(inputSource, xrFrameOfRef);
    if (!inputPose) {
    continue;
    }
    if (inputPose.gripMatrix) {
    // Render a virtual version of the input device
    //   at the correct position and orientation.
    }
    if (inputPose.pointerMatrix) {
    // Draw a ray from the gripMatrix to the pointerMatrix.
    }
}

Ini adalah versi yang disederhanakan dari contoh Pelacakan Input dari Grup Komunitas Web Imersif. Seperti halnya rendering frame, Anda dapat menggambar sinar pointer dan perangkat. Seperti yang telah dibahas sebelumnya, kode ini harus dijalankan sebagai bagian dari loop render.

Memilih item di ruang virtual

Hanya menunjuk ke berbagai hal dalam AR/VR sangat tidak berguna. Untuk melakukan hal yang berguna, pengguna memerlukan kemampuan untuk memilih sesuatu. WebXR Device API menyediakan tiga peristiwa untuk merespons interaksi pengguna: select, selectStart, dan selectEnd. Peristiwa ini memiliki keanehan yang tidak saya duga: peristiwa ini hanya memberi tahu Anda bahwa perangkat input telah diklik. Peristiwa ini tidak memberi tahu Anda item apa di lingkungan yang diklik. Pengendali peristiwa ditambahkan ke objek XRSession dan harus ditambahkan segera setelah tersedia.

xrDevice.requestSession(sessionOptions)
.then(xrSession => {
    // Create a WebGL layer and initialize the render loop.
    xrSession.addEventListener('selectstart', onSelectStart);
    xrSession.addEventListener('selectend', onSelectEnd);
    xrSession.addEventListener('select', onSelect);
});

Kode ini didasarkan pada contoh Pemilihan Input, jika Anda menginginkan lebih banyak konteks.

Untuk mengetahui apa yang diklik, Anda menggunakan sebuah pose. (Apakah Anda terkejut? Saya tidak begitu yakin.) Detailnya bersifat khusus untuk aplikasi Anda atau framework apa pun yang Anda gunakan, sehingga di luar cakupan artikel ini. Pendekatan Cottontail ada dalam contoh Pemilihan Input.

function onSelect(ev) {
    let inputPose = ev.frame.getInputPose(ev.inputSource, xrFrameOfRef);
    if (!inputPose) {
    return;
    }
    if (inputPose.pointerMatrix) {
    // Figure out what was clicked and respond.
    }
}

Kesimpulan: melihat ke depan

Seperti yang saya katakan sebelumnya, augmented reality diharapkan hadir di Chrome 69 (Canary pada Juni 2018). Namun, sebaiknya Anda mencoba apa yang telah kita miliki sejauh ini. Kami memerlukan masukan untuk meningkatkan kualitasnya. Ikuti progresnya dengan melihat ChromeStatus.com untuk Hit Test WebXR. Anda juga dapat mengikuti WebXR Anchors yang akan meningkatkan pelacakan pose.