בדף הזה מוסבר איך ליצור אפליקציית AR פשוטה וסוחפת באמצעות WebXR.
כדי להתחיל, נדרשת סביבת פיתוח תואמת ל-WebXR.
יצירת דף HTML
כדי להתחיל סשן ב-WebXR, נדרשת אינטראקציה עם המשתמש.
יש ליצור לחצן שמתקשר אל activateXR()
. לאחר טעינת הדף, המשתמש יוכל להשתמש בלחצן הזה כדי להתחיל את חוויית ה-AR.
יוצרים קובץ חדש בשם index.html
ומוסיפים לו את קוד ה-HTML הבא:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>Hello WebXR!</title>
<!-- three.js -->
<script src="https://unpkg.com/three@0.126.0/build/three.js"></script>
</head>
<body>
<!-- Starting an immersive WebXR session requires user interaction.
We start this one with a simple button. -->
<button onclick="activateXR()">Start Hello WebXR</button>
<script>
async function activateXR() {
// Add a canvas element and initialize a WebGL context that is compatible with WebXR.
const canvas = document.createElement("canvas");
document.body.appendChild(canvas);
const gl = canvas.getContext("webgl", {xrCompatible: true});
// To be continued in upcoming steps.
}
</script>
</body>
</html>
אתחול שלושה.js
לא יקרה הרבה כשלוחצים על הלחצן 'התחלה'. כדי להגדיר סביבה בתלת-ממד, אפשר להשתמש בספריית עיבוד להצגת סצנה.
בדוגמה הזו נשתמש ב-three.js
, ספריית עיבוד תלת-ממד של JavaScript שמספקת מעבד WebGL. Three.js
מטפל בעיבוד, במצלמות ובגרפים של סצנות כדי להקל על הצגת תוכן בתלת-ממד באינטרנט.
יצירת סצנה
בדרך כלל, המודל של סביבה תלת-ממדית מתואר כסצנה. יוצרים רכיב THREE.Scene
שמכיל רכיבי AR.
הקוד הבא מאפשר לכם לראות תיבה צבעונית לא מוארת ב-AR.
מוסיפים את הקוד הבא בחלק התחתון של הפונקציה activateXR()
:
const scene = new THREE.Scene();
// The cube will have a different color on each side.
const materials = [
new THREE.MeshBasicMaterial({color: 0xff0000}),
new THREE.MeshBasicMaterial({color: 0x0000ff}),
new THREE.MeshBasicMaterial({color: 0x00ff00}),
new THREE.MeshBasicMaterial({color: 0xff00ff}),
new THREE.MeshBasicMaterial({color: 0x00ffff}),
new THREE.MeshBasicMaterial({color: 0xffff00})
];
// Create the cube and add it to the demo scene.
const cube = new THREE.Mesh(new THREE.BoxBufferGeometry(0.2, 0.2, 0.2), materials);
cube.position.set(1, 1, 1);
scene.add(cube);
הגדרת רינדור באמצעות שלושה.js
כדי לצפות בסצנה הזו ב-AR, צריך כלי לעיבוד ומצלמה. הכלי לעיבוד משתמש ב-WebGL כדי לשרטט את הסצנה במסך. המצלמה מתארת את אזור התצוגה שממנו נראית הסצנה.
מוסיפים את הקוד הבא בחלק התחתון של הפונקציה activateXR()
:
// Set up the WebGLRenderer, which handles rendering to the session's base layer.
const renderer = new THREE.WebGLRenderer({
alpha: true,
preserveDrawingBuffer: true,
canvas: canvas,
context: gl
});
renderer.autoClear = false;
// The API directly updates the camera matrices.
// Disable matrix auto updates so three.js doesn't attempt
// to handle the matrices independently.
const camera = new THREE.PerspectiveCamera();
camera.matrixAutoUpdate = false;
יצירת XRSession
נקודת הכניסה אל WebXR היא דרך XRSystem.requestSession()
. צריך להשתמש במצב immersive-ar
כדי לאפשר הצגה של תוכן שעבר רינדור בסביבה בעולם האמיתי.
ב-XRReferenceSpace
מתוארת מערכת הקואורדינטות שמשמשת לאובייקטים בעולם הווירטואלי.
מצב 'local'
מתאים בצורה הטובה ביותר לחוויית AR, עם מרחב הפניה שמקורו בסמוך לצופה ומעקב יציב.
כדי ליצור XRSession
ו-XRReferenceSpace
, יש להוסיף את הקוד הבא בחלק התחתון של הפונקציה activateXR()
:
// Initialize a WebXR session using "immersive-ar".
const session = await navigator.xr.requestSession("immersive-ar");
session.updateRenderState({
baseLayer: new XRWebGLLayer(session, gl)
});
// A 'local' reference space has a native origin that is located
// near the viewer's position at the time the session was created.
const referenceSpace = await session.requestReferenceSpace('local');
עיבוד הסצנה
עכשיו אפשר לעבד את הסצנה. XRSession.requestAnimationFrame()
מתזמנת קריאה חוזרת (callback) שמתבצעת כשהדפדפן מוכן לשרטט מסגרת.
במהלך הקריאה החוזרת (callback) של המסגרת של האנימציה, צריך לבצע קריאה ל-XRFrame.getViewerPose()
כדי למצוא את תנוחת הצופה ביחס לשטח הקואורדינטות המקומי.
עדכון זה משמש לעדכון המצלמה במיקום ולשינוי האופן שבו המשתמש צופה בעולם הווירטואלי לפני שה-Renderer מצייר את הסצנה באמצעות המצלמה המעודכנת.
מוסיפים את הקוד הבא בחלק התחתון של הפונקציה activateXR()
:
// Create a render loop that allows us to draw on the AR view.
const onXRFrame = (time, frame) => {
// Queue up the next draw request.
session.requestAnimationFrame(onXRFrame);
// Bind the graphics framebuffer to the baseLayer's framebuffer
gl.bindFramebuffer(gl.FRAMEBUFFER, session.renderState.baseLayer.framebuffer)
// Retrieve the pose of the device.
// XRFrame.getViewerPose can return null while the session attempts to establish tracking.
const pose = frame.getViewerPose(referenceSpace);
if (pose) {
// In mobile AR, we only have one view.
const view = pose.views[0];
const viewport = session.renderState.baseLayer.getViewport(view);
renderer.setSize(viewport.width, viewport.height)
// Use the view's transform matrix and projection matrix to configure the THREE.camera.
camera.matrix.fromArray(view.transform.matrix)
camera.projectionMatrix.fromArray(view.projectionMatrix);
camera.updateMatrixWorld(true);
// Render the scene with THREE.WebGLRenderer.
renderer.render(scene, camera)
}
}
session.requestAnimationFrame(onXRFrame);
הרצת Hello WebXR
עוברים לקובץ WebXR במכשיר. אמורה להופיע קובייה צבעונית מכל הצדדים.
הוספת בדיקת היט
אחת הדרכים הנפוצות לאינטראקציה עם עולם ה-AR היא באמצעות בדיקת היט, שמוצאת צומת בין קרניים לבין גיאומטריה בעולם האמיתי. ב-Hello WebXR, עליך להציב חמנייה בעולם הווירטואלי באמצעות בדיקה של חמנייה.
הסרה של קוביית ההדגמה
מסירים את הקובייה הלא מוארת ומחליפים אותה בסצנה שכוללת תאורה:
const scene = new THREE.Scene();
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.3);
directionalLight.position.set(10, 15, 10);
scene.add(directionalLight);
שימוש בתכונה hit-test
כדי לאתחל את הפונקציונליות של בדיקת ההיט, צריך לבקש סשן עם התכונה hit-test
. מחפשים את הקטע הקודם של requestSession()
ומוסיפים לו hit-test
:
const session = await navigator.xr.requestSession("immersive-ar", {requiredFeatures: ['hit-test']});
הוספת טוען מודלים
בשלב הזה, הסצנה מכילה רק קובייה צבעונית. כדי שהחוויה תהיה מעניינת יותר, תוכלו להוסיף טוען מודלים שמאפשר לטעון דגמי GLTF.
בתג <head>
של המסמך, מוסיפים שלושת.js' GLTFLoader
.
<!-- three.js -->
<script src="https://unpkg.com/three@0.126.0/build/three.js"></script>
<script src="https://unpkg.com/three@0.126.0/examples/js/loaders/GLTFLoader.js"></script>
טעינת מודלים של GLTF
השתמש בטוען הדגם מהשלב הקודם כדי לטעון רשת מיקוד וחמנייה מהאינטרנט.
מוסיפים את הקוד הזה מעל onXRFrame
:
const loader = new THREE.GLTFLoader();
let reticle;
loader.load("https://immersive-web.github.io/webxr-samples/media/gltf/reticle/reticle.gltf", function(gltf) {
reticle = gltf.scene;
reticle.visible = false;
scene.add(reticle);
})
let flower;
loader.load("https://immersive-web.github.io/webxr-samples/media/gltf/sunflower/sunflower.gltf", function(gltf) {
flower = gltf.scene;
});
// Create a render loop that allows us to draw on the AR view.
const onXRFrame = (time, frame) => {
יצירת מקור לבדיקת היטים
כדי לחשב הצטלבויות עם אובייקטים בעולם האמיתי, צריך ליצור XRHitTestSource
באמצעות XRSession.requestHitTestSource()
.
ב-ray שמשמשת לבדיקת ההיט מוגדר מרחב ההפניות viewer
בתור המקור, כלומר שבדיקת ההיט מתבצעת מהמרכז של אזור התצוגה.
כדי ליצור מקור לבדיקת היט, צריך להוסיף את הקוד הבא אחרי שיוצרים את המרחב המשותף של local
:
// A 'local' reference space has a native origin that is located
// near the viewer's position at the time the session was created.
const referenceSpace = await session.requestReferenceSpace('local');
// Create another XRReferenceSpace that has the viewer as the origin.
const viewerSpace = await session.requestReferenceSpace('viewer');
// Perform hit testing using the viewer as origin.
const hitTestSource = await session.requestHitTestSource({ space: viewerSpace });
משרטטים רשת מיקוד
כדי להבהיר היכן תוצב החמנייה, הוסיפו רשת מיקוד לסצנה. נראה שרשת זו נצמדת למשטחים בעולם האמיתי, ומציינות את המיקום שבו תעוגל החמנייה.
XRFrame.getHitTestResults
מחזירה מערך של XRHitTestResult
וחושפת צמתים עם גיאומטריה מהעולם האמיתי.
השתמש בצמתים אלה כדי למקם את רשת המיקוד בכל מסגרת.
camera.projectionMatrix.fromArray(view.projectionMatrix);
camera.updateMatrixWorld(true);
const hitTestResults = frame.getHitTestResults(hitTestSource);
if (hitTestResults.length > 0 && reticle) {
const hitPose = hitTestResults[0].getPose(referenceSpace);
reticle.visible = true;
reticle.position.set(hitPose.transform.position.x, hitPose.transform.position.y, hitPose.transform.position.z)
reticle.updateMatrixWorld(true);
}
הוספת אינטראקציות בהקשה
הפרמטר XRSession
מקבל אירועים מסוג select
כשהמשתמש משלים פעולה ראשית.
בסשן AR, הפעולה הזו תואמת להקשה על המסך.
אפשר לגרום לחמנייה חדשה להופיע כשהמשתמש מקיש על המסך על ידי הוספת הקוד הבא במהלך האתחול:
let flower;
loader.load("https://immersive-web.github.io/webxr-samples/media/gltf/sunflower/sunflower.gltf", function(gltf) {
flower = gltf.scene;
});
session.addEventListener("select", (event) => {
if (flower) {
const clone = flower.clone();
clone.position.copy(reticle.position);
scene.add(clone);
}
});
בדיקת ההיט
צריך להשתמש במכשיר הנייד כדי לנווט לדף. לאחר ש-WebXR מבינה את הסביבה, הרשת צריכה להופיע על פני משטחים בעולם האמיתי. מקישים על המסך כדי למקם חמנייה. אפשר לראות אותה מכל הצדדים.
השלבים הבאים
- קוראים את המפרט של WebXR Device API.
- כדאי לעיין במסמכי תיעוד של WebXR במסמכי אינטרנט של MDN.
- כדאי לנסות את דוגמאות WebXR.
- איך ליצור אפליקציה של מציאות רבודה (AR) באמצעות WebXR Device API (Codelab).