واقعیت مجازی به وب می آید

چند نکته اساسی برای آماده کردن شما برای طیفی از تجربیات همهجانبه: واقعیت مجازی، واقعیت افزوده، و همه چیز در این بین.

جو مدلی
Joe Medley

تجربه‌های همهجانبه در Chrome 79 به وب آمدند. WebXR Device API واقعیت مجازی را ارائه می‌کند، در حالی که پشتیبانی از واقعیت افزوده در Chrome 81 ارائه می‌شود. در حالی که به‌روزرسانی GamePad API استفاده پیشرفته از کنترل‌ها را به VR گسترش می‌دهد. سایر مرورگرها به زودی از این مشخصات پشتیبانی خواهند کرد، از جمله Firefox Reality، مرورگر Oculus، مرورگر هلیو Edge و Magic Leap.

این مقاله مجموعه ای را در وب همه جانبه آغاز می کند. این قسط راه اندازی یک برنامه اصلی WebXR و همچنین ورود و خروج از یک جلسه XR را پوشش می دهد. مقاله‌های بعدی حلقه فریم (اسب کار تجربه WebXR)، ویژگی‌های واقعیت افزوده، و WebXR Hit Test API، ابزاری برای تشخیص سطوح در یک جلسه AR را پوشش خواهند داد. مگر اینکه خلاف آن ذکر شده باشد، هر چیزی که در این مقاله و مقاله های بعدی پوشش می دهم به طور یکسان برای واقعیت افزوده و واقعیت مجازی اعمال می شود.

وب همه جانبه چیست؟

اگرچه ما از دو اصطلاح برای توصیف تجربیات فراگیر استفاده می کنیم - واقعیت افزوده و واقعیت مجازی - بسیاری از آنها در طیفی از واقعیت کامل تا کاملا مجازی با درجاتی از غوطه ور شدن در بین آنها فکر می کنند. "X" در XR برای انعکاس آن تفکر از طریق نوعی متغیر جبری است که مخفف هر چیزی در طیف تجربیات غوطه‌ور است.

نموداری که طیف تجربیات بصری را از واقعیت کامل تا کاملاً غوطه ور نشان می دهد.
طیف تجارب فراگیر

نمونه هایی از تجربیات غوطه ور عبارتند از:

  • بازی ها
  • ویدیوهای 360 درجه
  • ویدیوهای دو بعدی (یا سه بعدی) سنتی که در محیطی غوطه ور ارائه می شوند
  • خرید خانه
  • قبل از خرید محصولات را در خانه خود مشاهده کنید
  • هنر فراگیر
  • چیز جالبی که هنوز کسی به آن فکر نکرده است

مفاهیم و کاربرد

من چند اصول اولیه استفاده از WebXR Device API را توضیح خواهم داد. اگر به عمق بیشتری از آنچه من ارائه کرده‌ام نیاز دارید، نمونه‌های WebXR گروه کاری Web Immersive یا مواد مرجع رو به رشد MDN را بررسی کنید. اگر با نسخه‌های اولیه WebXR Device API آشنا هستید، باید به همه این مطالب نگاهی بیندازید. تغییراتی بوده است.

کد موجود در این مقاله بر اساس نمونه‌های بی‌سابقه گروه کاری Immersive Web ( دمو ، منبع ) است، اما برای وضوح و سادگی ویرایش شده است.

بخشی از ایجاد مشخصات WebXR، ایجاد تدابیر امنیتی و حفظ حریم خصوصی برای محافظت از کاربران بوده است. در نتیجه، پیاده سازی ها باید الزامات خاصی را رعایت کنند. یک صفحه وب یا برنامه قبل از اینکه بتواند هر چیزی حساس را از بیننده درخواست کند باید فعال و متمرکز باشد. صفحات وب یا برنامه ها باید از طریق HTTPS ارائه شوند. خود API برای محافظت از اطلاعات به‌دست‌آمده از حسگرها و دوربین‌ها طراحی شده است که برای عملکرد به آن‌ها نیاز دارد.

درخواست یک جلسه

ورود به جلسه XR به یک حرکت کاربر نیاز دارد. برای دریافت آن، از تشخیص ویژگی برای آزمایش XRSystem (از طریق navigator.xr ) استفاده کنید و با XRSystem.isSessionSupported() تماس بگیرید. توجه داشته باشید که در نسخه های 79 و 80 کروم، شی XRSystem XR نامیده می شد.

در مثال زیر، من نشان داده‌ام که می‌خواهم یک جلسه واقعیت مجازی با نوع جلسه 'immersive-vr' داشته باشم. انواع دیگر جلسات عبارتند از 'immersive-ar' و 'inline' . یک جلسه درون خطی برای ارائه محتوا در HTML است و عمدتاً برای محتوای تیزر استفاده می شود. نمونه Immersive AR Session این را نشان می دهد. در مقاله بعدی توضیح خواهم داد.

وقتی متوجه شدم جلسات واقعیت مجازی پشتیبانی می‌شوند، دکمه‌ای را فعال می‌کنم که به من امکان می‌دهد ژست کاربر را دریافت کنم.

if (navigator.xr) {
  const supported = await navigator.xr.isSessionSupported('immersive-vr');
  if (supported) {
    xrButton.addEventListener('click', onButtonClicked);
    xrButton.textContent = 'Enter VR';
    xrButton.enabled = supported; // supported is Boolean
  }
}

پس از فعال کردن دکمه، منتظر یک رویداد کلیک می‌شوم و سپس درخواست جلسه می‌کنم.

let xrSession = null;
function onButtonClicked() {
  if (!xrSession) {
    navigator.xr.requestSession('immersive-vr')
    .then((session) => {
      xrSession = session;
      xrButton.textContent = 'Exit XR';
      onSessionStarted(xrSession);
    });
  } else {
    xrSession.end();
  }
}

به سلسله مراتب شی در این کد توجه کنید. از navigator به xr به یک نمونه XRSession حرکت می کند. در نسخه های اولیه API، یک اسکریپت باید قبل از درخواست جلسه، یک دستگاه را درخواست می کرد. در حال حاضر، دستگاه به طور ضمنی به دست آمده است.

وارد یک جلسه شوید

بعد از گرفتن یک جلسه، باید آن را شروع کنم و وارد آن شوم. اما ابتدا باید چند مورد را تنظیم کنم. یک جلسه به یک کنترل کننده رویداد onend نیاز دارد تا برنامه یا صفحه وب هنگام خروج کاربر بازنشانی شود.

من همچنین به یک عنصر <canvas> برای ترسیم صحنه خود نیاز دارم. باید یک WebGLRenderingContext یا WebGL2RenderingContext سازگار با XR باشد. تمام طراحی ها با استفاده از آنها یا یک چارچوب مبتنی بر WebGL مانند Three.js انجام می شود.

حالا که جایی برای نقاشی دارم، به منبعی از محتوا نیاز دارم تا روی آن نقاشی بکشم. برای آن، من یک نمونه از XRWebGLLayer ایجاد می کنم. با فراخوانی XRSession.updateRenderState() آن را با بوم مرتبط می کنم.

هنگامی که در یک جلسه هستم، به روشی نیاز دارم تا تعیین کنم که چیزها در واقعیت مجازی کجا هستند. من به یک فضای مرجع نیاز دارم. فضای مرجع 'local-floor' فضایی است که مبدا در نزدیکی بیننده قرار دارد و محور y در سطح طبقه 0 است و انتظار نمی رود که حرکت کند. انواع دیگری از فضاهای مرجع وجود دارد، اما این موضوع پیچیده‌تر از آن است که بتوانم در اینجا به آن بپردازم. من فضای مرجع را در یک متغیر ذخیره می‌کنم زیرا وقتی روی صفحه می‌کشم به آن نیاز دارم.

function onSessionStarted(xrSession) {
  xrSession.addEventListener('end', onSessionEnded);

  let canvas = document.createElement('canvas');
  webGLRenContext = canvas.getContext('webgl', { xrCompatible: true });

  xrSession.updateRenderState({
    baseLayer: new XRWebGLLayer(xrSession, webGLRenContext)
  });

  xrSession.requestReferenceSpace('local-floor')
  .then((refSpace) => {
    xrRefSpace = refSpace;
    xrSession.requestAnimationFrame(onXRFrame);
  });
}

پس از دریافت یک فضای مرجع، XRSession.requestAnimationFrame() را فراخوانی می کنم. این شروع ارائه محتوای مجازی است که در حلقه فریم انجام می شود.

یک حلقه فریم را اجرا کنید

حلقه فریم یک حلقه بی نهایت کنترل شده توسط کاربر است که در آن محتوا به طور مکرر به صفحه نمایش کشیده می شود. محتوا در بلوک های مجزا به نام فریم ترسیم می شود. متوالی فریم ها توهم حرکت را ایجاد می کند. برای برنامه های VR، فریم در ثانیه می تواند از 60 تا 144 باشد. AR برای اندروید با سرعت 30 فریم در ثانیه اجرا می شود. کد شما نباید نرخ فریم خاصی را در نظر بگیرد.

فرآیند اصلی برای حلقه فریم به شرح زیر است:

  1. XRSession.requestAnimationFrame() را فراخوانی کنید. در پاسخ، عامل کاربر XRFrameRequestCallback را فراخوانی می کند که توسط شما تعریف شده است.
  2. داخل تابع پاسخ به تماس شما:
    1. دوباره XRSession.requestAnimationFrame() فراخوانی کنید.
    2. ژست بیننده را بگیرید.
    3. WebGLFramebuffer از XRWebGLLayer به WebGLRenderingContext منتقل کنید ('bind').
    4. تکرار روی هر شی XRView ، بازیابی XRViewport آن از XRWebGLLayer و ارسال آن به WebGLRenderingContext .
    5. چیزی را به فریم بافر بکشید.

در ادامه این مقاله، مرحله 1 و بخشی از مرحله 2، راه اندازی و فراخوانی XRFrameRequestCallback توضیح داده شده است. موارد باقی مانده از مرحله 2 در بخش II پوشش داده شده است.

XRFrameRequestCallback

XRFrameRequestCallback توسط شما تعریف شده است. دو پارامتر نیاز دارد: یک DOMHighResTimeStamp و یک نمونه XRFrame . شی XRFrame اطلاعات مورد نیاز برای ارائه یک فریم به نمایشگر را فراهم می کند. آرگومان DOMHighResTimeStamp برای استفاده در آینده است.

قبل از انجام هر کار دیگری، من قصد دارم فریم انیمیشن بعدی را درخواست کنم. همانطور که قبلا گفته شد، زمان بندی فریم ها توسط عامل کاربر بر اساس سخت افزار زیرین تعیین می شود. درخواست فریم بعدی در ابتدا تضمین می‌کند که اگر چیزی در حین فراخوانی خطایی ایجاد کند، حلقه فریم ادامه می‌یابد.

function onXRFrame(hrTime, xrFrame) {
  let xrSession = xrFrame.session;
  xrSession.requestAnimationFrame(onXRFrame);
  // Render a frame.
}

در این مرحله، وقت آن است که چیزی برای بیننده ترسیم کنیم. این یک بحث برای قسمت دوم است. قبل از رفتن به آنجا، اجازه دهید به شما نشان دهم چگونه یک جلسه را پایان دهید.

جلسه را تمام کنید

یک جلسه فراگیر ممکن است به دلایل مختلفی از جمله پایان یافتن با کد خود از طریق تماس با XRSession.end() پایان یابد. دلایل دیگر شامل قطع شدن هدست یا کنترل آن توسط برنامه دیگری است. به همین دلیل است که یک برنامه کاربردی با رفتار خوب باید رویداد end را نظارت کند. وقتی رخ داد، جلسه و اشیاء رندر مربوط به آن را کنار بگذارید. یک جلسه همه جانبه پایان یافته را نمی توان از سر گرفت. برای ورود مجدد به تجربه همهجانبه، برنامه من باید جلسه جدیدی را شروع کند.

از Entering a session به یاد بیاورید که در حین راه اندازی، یک کنترل کننده رویداد onend اضافه کردم.

function onSessionStarted(xrSession) {
  xrSession.addEventListener('end', onSessionEnded);
  // More setup…
}

در کنترل کننده رویداد، قبل از ورود کاربر به جلسه، وضعیت برنامه را بازیابی کنید.

function onSessionEnded(event) {
  xrSession = null;
  xrButton.textContent = 'Enter VR';
}

نتیجه

من هر چیزی که برای نوشتن یک برنامه Web XR یا AR نیاز دارید را توضیح نداده ام. امیدوارم، من به اندازه کافی به شما داده ام تا بتوانید رمز را برای خودتان درک کنید، و به اندازه کافی برای شروع آزمایش کردن. در مقاله بعدی، حلقه فریم را توضیح خواهم داد، جایی که محتوا به صفحه نمایش کشیده می شود.

عکس توسط JESHOOTS.COM در Unsplash