واقعیت افزوده: ممکن است از قبل آن را بدانید

اگر قبلاً از WebXR Device API استفاده کرده‌اید، بیشترین راه را دارید.

جو مدلی
Joe Medley

WebXR Device API پاییز گذشته در Chrome 79 ارسال شد. همانطور که قبلاً گفته شد، اجرای Chrome از API در حال انجام است. کروم با خوشحالی اعلام می کند که برخی از کارها به پایان رسیده است. در کروم 81، دو ویژگی جدید وارد شده است:

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

برای اطلاعات در مورد تست ضربه، به مقاله همراه موقعیت یابی اشیاء مجازی در نماهای دنیای واقعی مراجعه کنید. کد موجود در این مقاله بر اساس نمونه Immersive AR Session ( منبع آزمایشی ) از نمونه های API دستگاه WebXR گروه کاری Immersive Web است.

قبل از ورود به کد، باید حداقل یک بار از نمونه جلسه AR Immersive استفاده کنید. به یک تلفن Android مدرن با Chrome 81 یا جدیدتر نیاز دارید.

چه فایده ای دارد؟

واقعیت افزوده افزوده ارزشمندی به بسیاری از صفحات وب موجود یا جدید خواهد بود که به آنها اجازه می دهد موارد استفاده AR را بدون ترک مرورگر پیاده سازی کنند. به عنوان مثال، می‌تواند به افراد کمک کند تا در سایت‌های آموزشی یاد بگیرند و به خریداران بالقوه اجازه می‌دهد هنگام خرید، اشیاء موجود در خانه خود را تجسم کنند.

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

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

درخواست جلسه

درخواست یک جلسه بسیار شبیه چیزی است که قبلاً دیده اید. ابتدا با فراخوانی xr.isSessionSupported() متوجه شوید که نوع جلسه مورد نظر در دستگاه فعلی موجود است یا خیر. به جای درخواست 'immersive-vr' مانند قبل، 'immersive-ar' را درخواست کنید.

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

مانند قبل، این دکمه "Enter AR" را فعال می کند. هنگامی که کاربر روی آن کلیک کرد، xr.requestSession() را فراخوانی کرد و 'immersive-ar' نیز ارسال کرد.

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

یک ملک راحتی

احتمالاً متوجه شده اید که من دو خط را در آخرین نمونه کد برجسته کردم. به نظر می رسد شیء XRSession دارای خاصیتی به نام isImmersive باشد. این یک ویژگی راحتی است که من خودم ایجاد کرده‌ام، و بخشی از مشخصات نیست. بعداً از آن برای تصمیم گیری در مورد اینکه چه چیزی به بیننده نشان دهم استفاده خواهم کرد. چرا این ویژگی بخشی از API نیست؟ از آنجا که ممکن است برنامه شما نیاز به ردیابی این ویژگی متفاوت داشته باشد، بنابراین نویسندگان مشخصات تصمیم گرفتند API را تمیز نگه دارند.

ورود به جلسه

به یاد بیاورید که onSessionStarted() در مقاله قبلی من چگونه بود:

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

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

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

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

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

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

  if (session.isImmersive) {
    removeBackground();
  }

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

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

  refSpaceType = xrSession.isImmersive ? 'local' : 'viewer';
  xrSession.requestReferenceSpace(refSpaceType).then((refSpace) => {
    xrSession.requestAnimationFrame(onXRFrame);
  });

}

فضاهای مرجع

مقالات قبلی من به فضاهای مرجع نگاه می کردند. نمونه ای که من توضیح می دهم از دو مورد از آنها استفاده می کند، بنابراین وقت آن است که آن حذف را اصلاح کنیم.

فضای مرجع رابطه بین دنیای مجازی و محیط فیزیکی کاربر را توصیف می کند. این کار را توسط:

  • تعیین مبدا برای سیستم مختصات مورد استفاده برای بیان موقعیت ها در دنیای مجازی.
  • تعیین اینکه آیا کاربر انتظار می رود در آن سیستم مختصات حرکت کند یا خیر.
  • آیا آن سیستم مختصات دارای مرزهای از پیش تعیین شده است. (نمونه های نشان داده شده در اینجا از سیستم مختصات با مرزهای از پیش تعیین شده استفاده نمی کنند.)

برای تمام فضاهای مرجع، مختصات X بیانگر چپ و راست، Y بیانگر بالا و پایین، و Z بیانگر جلو و عقب است. مقادیر مثبت به ترتیب درست، بالا و عقب هستند.

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

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

  if (session.isImmersive) {
    removeBackground();
  }

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

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

  refSpaceType = xrSession.isImmersive ? 'local' : 'viewer';
  xrSession.requestReferenceSpace(refSpaceType).then((refSpace) => {
    xrSession.requestAnimationFrame(onXRFrame);
  });
}

اگر از Immersive AR Session Sample بازدید کرده باشید، متوجه خواهید شد که در ابتدا صحنه ثابت است و اصلاً واقعیت افزوده نیست. برای حرکت در صحنه می توانید با انگشت خود بکشید و بکشید. اگر روی «START AR» کلیک کنید، پس‌زمینه از بین می‌رود و می‌توانید با حرکت دادن دستگاه در صحنه حرکت کنید. حالت ها از انواع مختلف فضای مرجع استفاده می کنند. متن برجسته شده بالا نحوه انتخاب این را نشان می دهد. از انواع مرجع زیر استفاده می کند:

local - مبدأ در موقعیت بیننده در زمان ایجاد جلسه است. این بدان معناست که تجربه لزوماً دارای یک طبقه کاملاً مشخص نیست و موقعیت دقیق مبدا ممکن است بسته به پلت فرم متفاوت باشد. اگرچه هیچ مرز از پیش تعیین شده ای برای فضا وجود ندارد، انتظار می رود که محتوا را بتوان بدون حرکتی به جز چرخش مشاهده کرد. همانطور که از مثال AR خودمان می بینید، ممکن است برخی حرکت ها در فضا امکان پذیر باشد.

viewer - بیشتر برای محتوای ارائه شده به صورت درونی در صفحه استفاده می شود، این فضا از دستگاه مشاهده پیروی می کند. هنگامی که به getViewerPose منتقل می شود، هیچ ردیابی را ارائه نمی دهد، و بنابراین همیشه یک وضعیت را در مبدا گزارش می دهد، مگر اینکه برنامه آن را با XRReferenceSpace.getOffsetReferenceSpace() تغییر دهد. نمونه از این برای فعال کردن سوژه‌های لمسی دوربین استفاده می‌کند.

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

از نظر مفهومی، هیچ تغییری نسبت به آنچه در جلسه VR انجام دادم که در مقاله‌های قبلی‌ام توضیح داده شد، تغییر نمی‌کند. نوع فضای مرجع را به XRFrame.getViewerPose() منتقل کنید. XRViewerPose برگشتی برای نوع فضای مرجع فعلی خواهد بود. استفاده از viewer به عنوان پیش‌فرض به صفحه اجازه می‌دهد پیش‌نمایش محتوا را قبل از درخواست رضایت کاربر برای واقعیت افزوده یا واقعیت مجازی نشان دهد. این یک نکته مهم را نشان می دهد: محتوای درون خطی از حلقه فریم مشابه با محتوای غوطه ور استفاده می کند و مقدار کدی را که باید حفظ شود کاهش می دهد.

function onXRFrame(hrTime, xrFrame) {
  let xrSession = xrFrame.session;
  xrSession.requestAnimationFrame(onXRFrame);
  let xrViewerPose = xrFrame.getViewerPose(refSpaceType);
  if (xrViewerPose) {
    // Render based on the pose.
  }
}

نتیجه

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

عکس دیوید گراندموگین در Unsplash