با استفاده از WebXR یک جلسه AR همهجانبه ایجاد کنید

این صفحه شما را از طریق ایجاد یک برنامه 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 را مقداردهی اولیه کنید

با فشار دادن دکمه Start اتفاق زیادی نمی افتد. برای تنظیم یک محیط سه بعدی، می توانید از یک کتابخانه رندر برای نمایش یک صحنه استفاده کنید.

در این مثال، شما three.js استفاده خواهید کرد، یک کتابخانه رندر سه بعدی جاوا اسکریپت که یک رندر 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);

رندرینگ را با استفاده از three.js تنظیم کنید

برای اینکه بتوانید این صحنه را در واقعیت افزوده مشاهده کنید، به یک رندر و یک دوربین نیاز دارید. رندر از 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' با فضای مرجعی که مبدأ نزدیک بیننده و ردیابی پایدار دارد، بهترین گزینه برای تجربه واقعیت افزوده است.

برای ایجاد یک 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() یک تماس برگشتی را برنامه ریزی می کند که زمانی اجرا می شود که مرورگر آماده ترسیم یک فریم باشد.

در طول بازخوانی فریم انیمیشن، XRFrame.getViewerPose() را فراخوانی کنید تا وضعیت بیننده را نسبت به فضای مختصات محلی به دست آورید. این برای به روز رسانی دوربین درون صحنه استفاده می شود و نحوه مشاهده کاربر از دنیای مجازی قبل از ترسیم صحنه با استفاده از دوربین به روز شده توسط رندر کننده استفاده می شود.

این کد را به پایین تابع 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 دستگاه خود بروید. شما باید بتوانید یک مکعب رنگی را از همه طرف مشاهده کنید.

یک تست ضربه اضافه کنید

یک راه متداول برای تعامل با دنیای واقعیت افزوده از طریق تست ضربه است که تقاطع بین یک پرتو و هندسه دنیای واقعی را پیدا می کند. در 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> سند خود، GLTFLoader three.js را اضافه کنید.

<!-- 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() ایجاد کنید. پرتو مورد استفاده برای تست ضربه دارای فضای مرجع 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 درکی از محیط ایجاد کرد، شبکه باید در سطوح واقعی ظاهر شود. برای قرار دادن یک گل آفتابگردان، که از همه طرف قابل مشاهده است، روی صفحه ضربه بزنید.

مراحل بعدی