Selamat datang di web imersif

Web imersif berarti pengalaman dunia virtual yang dihosting melalui browser. Seluruh pengalaman virtual reality ini ditampilkan di browser atau 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 Daydream Google, 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 menggambarkan pengalaman imersif, keduanya harus dianggap sebagai spektrum dari realitas lengkap hingga lingkungan VR yang sepenuhnya imersif, dengan berbagai level AR.

Contoh pengalaman yang imersif meliputi:

  • Video 360° yang imersif
  • Video 2D (atau 3D) tradisional yang disajikan di lingkungan yang imersif
  • Visualisasi data
  • Belanja di rumah
  • Seni
  • Sesuatu yang keren belum ada yang terlintas di pikiran

Bagaimana saya bisa ke sana?

Kini web imersif telah tersedia selama hampir setahun dalam bentuk embrionik. 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.

Sekarang, saatnya untuk melanjutkan.

Uji coba origin berakhir pada 24 Juli 2018, dan spesifikasi tersebut telah digantikan oleh WebXR Device API dan uji coba origin baru.

Apa yang terjadi pada WebVR 1.1?

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

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

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

Apa itu 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 di XR dimaksudkan sebagai variabel aljabar yang merupakan singkatan dari apa pun dalam spektrum pengalaman imersif. Fitur ini tersedia dalam uji coba origin yang disebutkan sebelumnya serta melalui polyfill.

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

Masih banyak lagi yang bisa saya bahas terkait API baru ini dalam artikel seperti ini. Saya ingin memberi Anda informasi yang cukup untuk mulai memahami contoh WebXR. Anda dapat menemukan informasi selengkapnya di penjelasan asli dan Panduan Pengguna Awal Web Imersif kami. Saya akan memperluasnya lagi seiring berlangsungnya uji coba origin. Jangan ragu untuk membuka masalah atau mengirimkan permintaan pull.

Untuk artikel ini, saya akan membahas cara memulai, menghentikan, dan menjalankan sesi XR, serta beberapa pengetahuan 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. Terserah Anda. Menggambar dilakukan menggunakan WebGL API. Anda dapat melakukan itu jika Anda benar-benar ambisius. Namun, sebaiknya gunakan framework. Contoh web imersif menggunakan contoh yang dibuat khusus untuk demo yang disebut Cottontail. Three.js telah mendukung WebXR sejak Mei. Saya tidak mendengar apa-apa tentang A-Frame.

Memulai dan menjalankan aplikasi

Proses dasarnya adalah:

  1. Minta perangkat XR.
  2. Jika tersedia, minta sesi XR. Jika Anda ingin pengguna menempatkan ponselnya di headset, sesi 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. Gambar konten yang sesuai ke layar di setiap {i>frame<i}.
  4. Jalankan loop render hingga pengguna memutuskan untuk keluar.
  5. Akhiri sesi XR.

Mari kita lihat hal ini secara lebih detail dan menyertakan beberapa kode. Anda tidak akan dapat menjalankan aplikasi dari apa yang akan saya tunjukkan. Namun, sekali lagi, ini hanya untuk memperjelasnya.

Meminta perangkat XR

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

Jika tidak menggunakan sesi imersif, Anda dapat melewati iklan fungsi dan mendapatkan gestur pengguna dan langsung meminta sesi. Sesi imersif adalah sesi yang memerlukan headset. Sesi yang tidak imersif hanya menampilkan konten di layar perangkat. Yang pertama adalah apa yang dipikirkan banyak orang saat Anda menyebut 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

Sekarang setelah kita memiliki perangkat dan {i>gesture <i}pengguna, tiba saatnya untuk mendapatkan sesi. Untuk membuat sesi, browser membutuhkan kanvas untuk 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 membutuhkan sedikit penguraian. Untuk menyelesaikannya, saya akan memberikan banyak kata kepada Anda. Jika Anda ingin mengintip kode akhir, langsung ke depan untuk melihat sekilas, lalu kembali untuk melihat penjelasan lengkapnya. Ada banyak hal yang mungkin tidak dapat Anda pahami.

Proses dasar untuk loop render adalah:

  1. Meminta bingkai animasi.
  2. Membuat kueri posisi perangkat.
  3. Gambar konten ke posisi perangkat berdasarkan posisinya.
  4. Melakukan pekerjaan yang diperlukan untuk perangkat input.
  5. Ulangi 60 kali per detik sampai pengguna memutuskan untuk berhenti.

Meminta bingkai presentasi

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

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

Sebelum saya menjelaskan hal lainnya kepada Anda, saya akan memberikan beberapa kode. Contoh di bawah ini menunjukkan cara loop render dimulai dan dipertahankan. Perhatikan penggunaan ganda dari {i>word frame<i}. Lalu, 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 arah perangkat tampilan dan Anda memerlukan akses ke layar. Secara umum, posisi dan orientasi sesuatu dalam AR/VR disebut pose. Baik pelihat maupun perangkat input memiliki pose. (Saya akan membahas perangkat input nanti.) Pose perangkat penampil dan input ditentukan sebagai matriks berukuran 4x4 yang disimpan dalam Float32Array dalam urutan utama kolom. Anda mendapatkan pose pelihat dengan memanggil XRFrame.getDevicePose() pada objek frame animasi saat ini. Selalu uji untuk melihat apakah Anda melakukan pose balik. Jika ada yang salah, Anda tentu tidak ingin menggambarnya di layar.

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

Penayangan

Setelah memeriksa pose, saatnya menggambar sesuatu. Objek yang menjadi tujuan menggambar disebut tampilan (XRView). Di sinilah jenis sesi menjadi penting. Tampilan diambil dari objek XRFrame sebagai array. Jika Anda berada dalam sesi yang tidak imersif, array 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.
}

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

Seluruh loop render

Jika saya menggabungkan semua ini, saya mendapatkan kode di bawah ini. Saya telah meninggalkan {i>placeholder<i} untuk perangkat input, yang akan saya bahas nanti.

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

Mengakhiri sesi XR

Sesi XR dapat berakhir karena beberapa alasan, termasuk diakhiri oleh kode Anda sendiri melalui panggilan ke XRSession.end(). Penyebab lainnya adalah 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?

Sama halnya dengan masa aktif aplikasi, saya hanya akan menunjukkan cara berinteraksi dengan objek dalam AR atau VR.

WebXR Device API menggunakan pendekatan "titik dan klik" terhadap input pengguna. Dengan pendekatan ini, setiap sumber input memiliki sinar pointer yang ditentukan untuk menunjukkan ke mana perangkat input menunjuk dan peristiwa untuk menunjukkan waktu sesuatu dipilih. Aplikasi Anda menggambar sinar pointer dan menunjukkan titik ujungnya. Saat pengguna mengklik perangkat input, peristiwa akan diaktifkan - khususnya select, selectStart, dan selectEnd. Aplikasi Anda menentukan konten yang diklik dan merespons dengan tepat.

Perangkat input dan sinar pointer

Bagi pengguna, sinar pointer hanyalah garis samar 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 dalam ruang AR/VR. Proses tersebut terlihat kira-kira 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 sederhana dari contoh Pelacakan Input dari Grup Komunitas Immersive Web. Seperti halnya rendering {i>frame<i}, terserah Anda untuk menggambar sinar pointer dan perangkatnya. Seperti disebutkan sebelumnya, kode ini harus dijalankan sebagai bagian dari loop render.

Memilih item di ruang virtual

Hanya menunjuk sesuatu dalam AR/VR sangat tidak berguna. Untuk melakukan sesuatu yang berguna, pengguna memerlukan kemampuan untuk memilih sesuatu. WebXR Device API menyediakan tiga peristiwa untuk merespons interaksi pengguna: select, selectStart, dan selectEnd. Mereka memiliki keunikan yang tidak saya sangka: mereka hanya memberi tahu bahwa perangkat input diklik. Informasi 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 Pilihan Input, jika Anda menginginkan lebih banyak konteks.

Untuk mengetahui apa yang diklik, Anda menggunakan sebuah pose. (Apakah Anda terkejut? Saya tidak berpikir demikian.) Detailnya berlaku khusus untuk aplikasi Anda atau framework apa pun yang digunakan, sehingga di luar cakupan artikel ini. Pendekatan Cottontail ada pada contoh Input Selection.

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 diperkirakan akan tersedia di Chrome 69 (Canary pada bulan Juni 2018). Meskipun demikian, sebaiknya Anda mencoba apa yang telah kami miliki sejauh ini. Kami membutuhkan masukan untuk membuatnya lebih baik. Ikuti kemajuannya dengan menonton ChromeStatus.com untuk WebXR Hit Test. Anda juga dapat mengikuti Anchor WebXR yang akan meningkatkan pelacakan pose.