1. Sebelum memulai
Codelab ini membahas contoh proses build aplikasi web AR. Contoh ini menggunakan JavaScript untuk merender model 3D yang muncul seolah-olah ada di dunia nyata.
Anda menggunakan WebXR Device API yang menggabungkan fungsi AR dan virtual reality (VR). Anda berfokus pada ekstensi AR ke WebXR Device API untuk membuat aplikasi AR sederhana yang berjalan di web interaktif.
Apa yang dimaksud dengan AR?
AR adalah istilah yang biasanya digunakan untuk menjelaskan gabungan grafis yang dihasilkan komputer dengan dunia nyata. Untuk AR berbasis ponsel, ini berarti menempatkan grafis komputer melalui feed kamera langsung dengan meyakinkan. Agar efek ini tetap realistis saat ponsel bergerak di dunia nyata, perangkat berkemampuan AR perlu memahami lingkungan nyata yang dilaluinya serta dapat menentukan posenya (posisi dan orientasi) dalam ruang 3D. Hal ini dapat mencakup pendeteksian permukaan dan memperkirakan pencahayaan lingkungan.
AR telah digunakan secara luas dalam aplikasi setelah rilis ARCore Google dan ARKit Apple, baik untuk filter selfie maupun game berbasis AR.
Yang akan Anda build
Dalam codelab ini, Anda akan membuat aplikasi web yang menempatkan model di dunia nyata menggunakan augmented reality. Aplikasi Anda akan:
- Menggunakan sensor perangkat target untuk menentukan dan melacak posisi serta orientasinya di dunia nyata
- Merender model 3D yang digabungkan di bagian atas tampilan kamera langsung
- Menjalankan hit test untuk menempatkan objek di atas permukaan yang ditemukan di dunia nyata
Yang akan Anda pelajari
- Cara menggunakan WebXR Device API
- Cara mengonfigurasi scene AR dasar
- Cara menemukan permukaan menggunakan hit test AR
- Cara memuat dan merender model 3D yang disinkronkan dengan feed kamera dunia nyata
- Cara merender bayangan berdasarkan model 3D
Codelab ini berfokus pada AR API. Konsep dan blok kode yang tidak-relevan akan dipoles dan disediakan untuk Anda dalam kode repositori yang sesuai.
Yang Anda butuhkan
- Workstation untuk coding dan hosting konten web statis
- Perangkat Android yang mendukung ARCore yang menjalankan Android 8.0 Oreo
- Google Chrome
- Layanan Google Play untuk AR yang diinstal (Chrome otomatis meminta Anda menginstalnya di perangkat yang kompatibel)
- Server web pilihan Anda
- Kabel USB untuk menghubungkan perangkat AR ke workstation Anda
- Kode contoh
- Editor teks
- Pengetahuan dasar tentang HTML, CSS, JavaScript, dan Google Chrome Developer Tools
Klik Coba di perangkat AR Anda untuk mencoba langkah pertama codelab ini. Jika Anda mendapatkan halaman dengan pesan "Browser Anda tidak memiliki fitur AR", pastikan Layanan Google Play untuk AR telah terinstal di perangkat Android Anda.
2. Menyiapkan lingkungan pengembangan
Download kodenya
- Klik link berikut guna mendownload semua kode untuk codelab ini di workstation Anda:
- Mengekstrak file zip yang didownload. Tindakan ini akan mengekstrak folder root (
ar-with-webxr-master
), yang berisi direktori yang menyediakan beberapa langkah codelab ini, beserta semua materi yang diperlukan.
Folder step-03
dan step-04
berisi status akhir yang diinginkan dari langkah ketiga dan keempat codelab ini, serta hasil final
. Folder tersebut disediakan sebagai referensi
Anda melakukan semua pekerjaan coding di direktori work
.
Menginstal server web
- Anda bebas untuk menggunakan server web Anda sendiri. Jika Anda belum menyiapkannya, bagian ini akan menjelaskan cara menyiapkan Server Web untuk Chrome.
Jika aplikasi tersebut belum diinstal di workstation, Anda dapat menginstalnya dari Chrome Web Store.
- Setelah menginstal aplikasi Server Web untuk Chrome, buka
chrome://apps
, lalu klik ikon Server Web:
Anda akan melihat dialog ini berikutnya, yang memungkinkan Anda mengonfigurasi server web lokal:
- Klik pilih folder, lalu pilih folder
ar-with-webxr-master
. Tindakan ini memungkinkan Anda menyalurkan pekerjaan yang sedang berlangsung melalui URL yang ditandai dalam dialog server web (di bagian URL Server Web). - Di bagian Opsi (perlu dimulai ulang), pilih kotak centang Tampilkan index.html secara otomatis..
- Alihkan tombol Server web ke Hentikan, lalu alihkan kembali ke Dimulai.
- Verifikasi bahwa setidaknya satu URL Server Web muncul: http://127.0.0.1:8887—URL localhost default.
Menyiapkan penerusan port
Konfigurasikan perangkat AR sehingga server web dapat mengakses port yang sama di workstation Anda saat mengunjungi localhost:8887.
- Di workstation pengembangan Anda, buka chrome://inspect, lalu klik Penerusan port...:
- Gunakan dialog Setelan penerusan port untuk meneruskan port 8887 ke localhost:8887.
- Pilih kotak centang Aktifkan penerusan port:
Memverifikasi penyiapan Anda
Uji koneksi Anda:
- Hubungkan perangkat AR ke workstation dengan kabel USB.
- Pada perangkat AR di Chrome, masukkan http://localhost:8887 di kolom URL. Perangkat AR Anda harus meneruskan permintaan ini ke server web workstation pengembangan. Anda akan melihat direktori file.
- Di perangkat AR, klik
step-03
untuk memuat filestep-03/index.html
di browser Anda.
Anda akan melihat halaman yang berisi tombol Mulai augmented reality | Namun, jika Anda melihat halaman error Browser tidak didukung, artinya perangkat Anda mungkin tidak kompatibel. |
Koneksi ke server web Anda kini akan berfungsi dengan perangkat AR.
- Klik Mulai augmented reality. Anda mungkin akan diminta untuk menginstal ARCore.
Anda akan melihat permintaan izin kamera saat pertama kali menjalankan aplikasi AR.
→
Setelah semuanya siap, Anda akan melihat scene kubus yang ditempatkan di atas feed kamera. Pemahaman scene meningkat saat lebih banyak bagian dunia nyata diurai oleh kamera, sehingga menggerakkannya dapat membantu menstabilkan berbagai hal.
3 Mengonfigurasi WebXR
Pada langkah ini, Anda akan mempelajari cara menyiapkan sesi WebXR dan scene AR dasar. Halaman HTML disediakan dengan gaya CSS dan JavaScript untuk mengaktifkan fungsi AR dasar. Hal ini mempercepat proses penyiapan, sehingga memungkinkan codelab berfokus pada fitur AR.
Halaman HTML
Anda mem-build pengalaman AR ke dalam halaman web tradisional menggunakan teknologi web yang sudah ada. Dalam pengalaman ini, Anda menggunakan kanvas yang merender layar penuh, sehingga file HTML tidak perlu harus terlalu rumit.
Fitur AR memerlukan gestur pengguna untuk memulai, sehingga ada beberapa komponen Desain Material untuk menampilkan tombol Mulai AR dan pesan browser yang tidak didukung.
File index.html
yang sudah ada dalam direktori work
Anda akan terlihat seperti berikut. Ini adalah subkumpulan konten yang sebenarnya; jangan menyalin kode ini ke file Anda.
<!-- Don't copy this code into your file! -->
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Building an augmented reality application with the WebXR Device API</title>
<link rel="stylesheet" href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css">
<script src="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js"></script>
<!-- three.js -->
<script src="https://unpkg.com/three@0.123.0/build/three.js"></script>
<script src="https://unpkg.com/three@0.123.0/examples/js/loaders/GLTFLoader.js"></script>
<script src="../shared/utils.js"></script>
<script src="app.js"></script>
</head>
<body>
<!-- Information about AR removed for brevity. -->
<!-- Starting an immersive WebXR session requires user interaction. Start the WebXR experience with a simple button. -->
<a onclick="activateXR()" class="mdc-button mdc-button--raised mdc-button--accent">
Start augmented reality
</a>
</body>
</html>
Membuka kode JavaScript kunci
Titik awal untuk aplikasi Anda adalah app.js
. File ini menyediakan beberapa boilerplate untuk menyiapkan pengalaman AR.
Direktori kerja Anda juga sudah menyertakan kode aplikasi (app.js
).
Memeriksa dukungan WebXR dan AR
Sebelum pengguna dapat menggunakan AR, periksa keberadaan navigator.xr
dan fitur XR yang diperlukan. Objek navigator.xr
adalah titik entri untuk WebXR Device API, sehingga objek ini harus ada jika perangkat ternyata kompatibel. Pastikan juga apakah mode sesi "immersive-ar"
didukung.
Jika semuanya berfungsi dengan baik, mengklik tombol Masuk augmented reality akan membuat sesi XR. Jika tidak, onNoXRDevice()
akan dipanggil (dalam shared/utils.js
) yang akan menampilkan pesan yang menunjukkan kurangnya dukungan AR.
Kode ini sudah ada di app.js
, sehingga Anda tidak perlu melakukan perubahan.
(async function() {
if (navigator.xr && await navigator.xr.isSessionSupported("immersive-ar")) {
document.getElementById("enter-ar").addEventListener("click", activateXR)
} else {
onNoXRDevice();
}
})();
Meminta XRSession
Saat Anda mengklik Masuk augmented reality, kode akan memanggil activateXR()
. Tindakan ini akan memulai pengalaman AR.
- Temukan fungsi
activateXR()
diapp.js
. Beberapa kode telah diabaikan:
activateXR = async () => {
// Initialize a WebXR session using "immersive-ar".
this.xrSession = /* TODO */;
// Omitted for brevity
}
Titik entri ke WebXR adalah melalui XRSystem.requestSession()
. Gunakan mode immersive-ar
agar konten yang dirender dapat dilihat di lingkungan dunia nyata.
- Melakukan inisialisasi
this.xrSession
menggunakan mode"immersive-ar"
:
activateXR = async () => {
// Initialize a WebXR session using "immersive-ar".
this.xrSession = await navigator.xr.requestSession("immersive-ar");
// ...
}
Melakukan inisialisasi XRReferenceSpace
XRReferenceSpace
menjelaskan sistem koordinat yang digunakan untuk objek yang ada dalam dunia virtual. Mode 'local'
sangat cocok digunakan untuk pengalaman AR, dengan ruang referensi yang memiliki asal di dekat penampil dan pelacakan yang stabil.
Melakukan inisialisasi this.localReferenceSpace
di onSessionStarted()
dengan kode berikut:
this.localReferenceSpace = await this.xrSession.requestReferenceSpace("local");
Menentukan loop animasi
- Gunakan
requestAnimationFrame
XRSession
untuk memulai loop rendering, yang mirip denganwindow.requestAnimationFrame
.
Pada setiap frame, onXRFrame
dipanggil dengan stempel waktu dan XRFrame.
- Selesaikan penerapan
onXRFrame
. Saat frame digambar, lakukan antrean di permintaan berikutnya dengan menambahkan:
// Queue up the next draw request.
this.xrSession.requestAnimationFrame(this.onXRFrame);
- Tambahkan kode untuk menyiapkan lingkungan grafis. Tambahkan ke bagian bawah
onXRFrame
:
// Bind the graphics framebuffer to the baseLayer's framebuffer.
const framebuffer = this.xrSession.renderState.baseLayer.framebuffer;
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebuffer);
this.renderer.setFramebuffer(framebuffer);
- Untuk menentukan pose penampil, gunakan
XRFrame.getViewerPose()
.XRViewerPose
ini menjelaskan posisi dan orientasi perangkat di ruang. Ini juga berisi arrayXRView
, yang menjelaskan setiap sudut pandang yang menjadi tempat untuk merender scene, agar dapat ditampilkan dengan benar di perangkat saat ini. Meskipun VR stereoskopis memiliki dua tampilan (satu untuk setiap mata), perangkat AR hanya memiliki satu tampilan.
Informasi dalampose.views
paling sering digunakan untuk mengonfigurasi matriks tampilan dan matriks proyeksi kamera virtual. Informasi ini memengaruhi cara scene ditata dalam 3D. Saat kamera dikonfigurasi, scene dapat dirender. - Tambahkan ke bagian bawah
onXRFrame
:
// Retrieve the pose of the device.
// XRFrame.getViewerPose can return null while the session attempts to establish tracking.
const pose = frame.getViewerPose(this.localReferenceSpace);
if (pose) {
// In mobile AR, we only have one view.
const view = pose.views[0];
const viewport = this.xrSession.renderState.baseLayer.getViewport(view);
this.renderer.setSize(viewport.width, viewport.height);
// Use the view's transform matrix and projection matrix to configure the THREE.camera.
this.camera.matrix.fromArray(view.transform.matrix);
this.camera.projectionMatrix.fromArray(view.projectionMatrix);
this.camera.updateMatrixWorld(true);
// Render the scene with THREE.WebGLRenderer.
this.renderer.render(this.scene, this.camera);
}
Melakukan pengujian
Jalankan aplikasi; di perangkat pengembangan Anda, buka work/index.html
. Anda akan melihat feed kamera dengan kubus yang mengambang di ruang tempat perspektifnya dapat berubah saat Anda menggerakkan perangkat. Pelacakan akan meningkat semakin Anda bergerak, jadi jelajahi apa yang sesuai untuk Anda dan perangkat Anda.
Jika Anda mengalami masalah saat menjalankan aplikasi, lihat bagian Pengantar dan Menyiapkan lingkungan pengembangan.
4. Menambahkan reticle penargetan
Setelah penyiapan scene AR dasar selesai, kini saatnya untuk mulai berinteraksi dengan dunia nyata menggunakan hit test. Di bagian ini, Anda akan memprogram hit test dan menggunakannya untuk menemukan permukaan di dunia nyata.
Memahami hit test
Hit test umumnya merupakan cara untuk membuang garis lurus dari sebuah titik di ruang ke beberapa arah dan menentukan apakah garis tersebut bersimpangan dengan objek yang diinginkan. Dalam contoh ini, Anda mengarahkan perangkat ke lokasi di dunia nyata. Bayangkan sebuah sinar berjalan dari kamera perangkat dan langsung memasuki dunia fisik di depannya.
WebXR Device API memungkinkan Anda mengetahui apakah sinar ini bersimpangan dengan objek di dunia nyata, yang ditentukan oleh kemampuan AR dan pemahamannya terhadap dunia nyata.
Meminta XRSession
dengan fitur tambahan
Untuk melakukan hit test, fitur tambahan diperlukan saat meminta XRSession
.
- Di
app.js
, temukannavigator.xr.requestSession
. - Tambahkan fitur
"hit-test"
dan"dom-overlay"
sebagairequiredFeature
seperti berikut:
this.xrSession = await navigator.xr.requestSession("immersive-ar", {
requiredFeatures: ["hit-test", "dom-overlay"]
});
- Konfigurasikan overlay DOM. Tambahkan lapisan elemen
document.body
ke tampilan kamera AR, seperti:
this.xrSession = await navigator.xr.requestSession("immersive-ar", {
requiredFeatures: ["hit-test", "dom-overlay"],
domOverlay: { root: document.body }
});
Menambahkan perintah gerakan
ARCore berfungsi sangat baik saat pemahaman yang memadai tentang lingkungan telah dibangun. Hal ini dilakukan melalui proses yang disebut pelokalan dan pemetaan simultan (SLAM), yang menggunakan poin fitur yang berbeda secara visual untuk menghitung perubahan lokasi dan karakteristik lingkungan.
Gunakan "dom-overlay"
dari langkah sebelumnya untuk menampilkan perintah gerakan di atas feed kamera.
Tambahkan <div>
ke index.html
dengan ID stabilization
. <div>
ini menampilkan animasi kepada pengguna yang mewakili status stabilisasi dan meminta mereka untuk bergerak di antara perangkat untuk meningkatkan proses SLAM. Animasi ini ditampilkan setelah pengguna berada dalam AR dan akan disembunyikan setelah reticle menemukan permukaan, yang dikontrol oleh class <body>
.
<div id="stabilization"></div>
</body>
</html>
Menambahkan reticle
Gunakan reticle untuk menunjukkan lokasi yang dituju oleh tampilan perangkat.
- Di
app.js
, ganti panggilanDemoUtils.createCubeScene()
disetupThreeJs()
denganThree.Scene()
yang kosong.
setupThreeJs() {
// ...
// this.scene = DemoUtils.createCubeScene();
this.scene = DemoUtils.createLitScene();
}
- Isi scene baru dengan objek yang mewakili titik persimpangan. Class
Reticle
yang disediakan menangani pemuatan model reticle dishared/utils.js
. - Tambahkan
Reticle
ke scene disetupThreeJs()
:
setupThreeJs() {
// ...
// this.scene = DemoUtils.createCubeScene();
this.scene = DemoUtils.createLitScene();
this.reticle = new Reticle();
this.scene.add(this.reticle);
}
Untuk melakukan hit test, gunakan XRReferenceSpace
yang baru. Ruang referensi ini menunjukkan sistem koordinat baru dari perspektif penampil untuk membuat sinar yang sejajar dengan arah tampilan. Sistem koordinat ini digunakan di XRSession.requestHitTestSource()
, yang dapat menghitung hit test.
- Tambahkan kode berikut ke
onSessionStarted()
diapp.js
:
async onSessionStarted() {
// ...
// Setup an XRReferenceSpace using the "local" coordinate system.
this.localReferenceSpace = await this.xrSession.requestReferenceSpace("local");
// Add these lines:
// Create another XRReferenceSpace that has the viewer as the origin.
this.viewerSpace = await this.xrSession.requestReferenceSpace("viewer");
// Perform hit testing using the viewer as origin.
this.hitTestSource = await this.xrSession.requestHitTestSource({ space: this.viewerSpace });
// ...
}
- Dengan
hitTestSource
ini, lakukan hit test setiap frame:- Jika tidak ada hasil yang keluar setelah melakukan hit test, artinya ARCore belum memiliki cukup waktu untuk membangun pemahaman tentang lingkungan sekitarnya. Dalam hal ini, minta pengguna untuk memindahkan perangkat menggunakan stabilisasi
<div>
. - Jika ada hasilnya, pindahkan reticle ke lokasi tersebut.
- Jika tidak ada hasil yang keluar setelah melakukan hit test, artinya ARCore belum memiliki cukup waktu untuk membangun pemahaman tentang lingkungan sekitarnya. Dalam hal ini, minta pengguna untuk memindahkan perangkat menggunakan stabilisasi
- Ubah
onXRFrame
untuk memindahkan reticle tersebut:
onXRFrame = (time, frame) => {
// ... some code omitted ...
this.camera.updateMatrixWorld(true);
// Add the following:
const hitTestResults = frame.getHitTestResults(this.hitTestSource);
if (!this.stabilized && hitTestResults.length > 0) {
this.stabilized = true;
document.body.classList.add("stabilized");
}
if (hitTestResults.length > 0) {
const hitPose = hitTestResults[0].getPose(this.localReferenceSpace);
// update the reticle position
this.reticle.visible = true;
this.reticle.position.set(hitPose.transform.position.x, hitPose.transform.position.y, hitPose.transform.position.z)
this.reticle.updateMatrixWorld(true);
}
// More code omitted.
}
Menambahkan perilaku pada ketukan layar
XRSession
dapat memunculkan peristiwa berdasarkan interaksi pengguna melalui peristiwa select
, yang mewakili tindakan utama. Di WebXR pada perangkat seluler, tindakan utamanya adalah ketukan layar.
- Tambahkan pemroses peristiwa
select
di bagian bawahonSessionStarted
:
this.xrSession.addEventListener("select", this.onSelect);
Dalam contoh ini, ketukan layar menyebabkan bunga matahari ditempatkan di reticle.
- Buat implementasi untuk
onSelect
di classApp
:
onSelect = () => {
if (window.sunflower) {
const clone = window.sunflower.clone();
clone.position.copy(this.reticle.position);
this.scene.add(clone);
}
}
Menguji aplikasi
Anda membuat reticle yang dapat ditargetkan menggunakan perangkat Anda menggunakan hit test. Saat mengetuk layar, Anda dapat menempatkan bunga matahari di lokasi yang ditunjuk reticle.
- Saat menjalankan aplikasi, Anda akan dapat melihat reticle yang melacak permukaan lantai. Jika tidak, coba lihat sekeliling secara perlahan dengan ponsel Anda.
- Ketuk reticle setelah Anda melihatnya. Bunga matahari harus ditempatkan di atasnya. Anda mungkin harus bergerak sedikit demi sedikit sehingga platform AR yang mendasarinya dapat mendeteksi permukaan dunia nyata dengan lebih baik. Pencahayaan rendah dan permukaan yang datar akan mengurangi kualitas pemahaman scene, dan meningkatkan peluang tidak ditemukannya hit. Jika Anda mengalami masalah, lihat kode
step-04/app.js
untuk melihat contoh kerja langkah ini.
5. Menambahkan bayangan
Membuat scene yang realistis melibatkan elemen seperti pencahayaan dan bayangan yang tepat pada objek digital yang akan menambahkan realisme dan detail imersif dalam scene tersebut.
Pencahayaan dan bayangan ditangani oleh three.js
. Anda dapat menentukan cahaya mana yang harus memunculkan bayangan, material mana yang harus menerima dan merender bayangan ini, dan mesh mana yang dapat memunculkan bayangan. Scene pada aplikasi ini berisi cahaya yang dapat memunculkan bayangan dan permukaan datar hanya untuk merender bayangan.
- Aktifkan bayangan di
three.js
WebGLRenderer
. Setelah membuat perender, setel nilai berikut padashadowMap
-nya:
setupThreeJs() {
...
this.renderer = new THREE.WebGLRenderer(...);
...
this.renderer.shadowMap.enabled = true;
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
...
}
Contoh scene yang dibuat dalam DemoUtils.createLitScene()
berisi objek yang disebut shadowMesh
, permukaan horizontal datar yang hanya merender bayangan. Permukaan ini awalnya memiliki posisi Y berisi 10.000 unit. Setelah bunga matahari ditempatkan, pindahkan shadowMesh
agar tingginya sama dengan permukaan dunia nyata, sehingga bayangan bunga dirender di atas tanah dunia nyata.
- Di
onSelect
, setelah menambahkanclone
ke scene tersebut, tambahkan kode untuk memposisikan ulang bidang bayangannya:
onSelect = () => {
if (window.sunflower) {
const clone = window.sunflower.clone();
clone.position.copy(this.reticle.position);
this.scene.add(clone);
const shadowMesh = this.scene.children.find(c => c.name === "shadowMesh");
shadowMesh.position.y = clone.position.y;
}
}
Melakukan pengujian
Saat menempatkan bunga matahari, Anda dapat melihatnya memunculkan bayangan. Jika Anda mengalami masalah, lihat kode final/app.js
untuk melihat contoh kerja langkah ini.
6. Referensi lainnya
Selamat! Anda sudah mencapai akhir bagian codelab ini mengenai AR menggunakan WebXR.