به وب همه جانبه خوش آمدید

وب همهجانبه به معنای تجربیات دنیای مجازی است که از طریق مرورگر میزبانی می شود. کل این تجربیات واقعیت مجازی در مرورگر یا هدست‌های دارای قابلیت واقعیت مجازی ظاهر شد.

جو مدلی
Joe Medley

وب همهجانبه به معنای تجربیات دنیای مجازی است که از طریق مرورگر میزبانی می شود. این شامل تمام تجربیات واقعیت مجازی (VR) است که در مرورگر یا هدست‌های دارای قابلیت واقعیت مجازی مانند Daydream Google، Oculus Rift، Samsung Gear VR، HTC Vive و هدست‌های واقعیت ترکیبی Windows ظاهر شده‌اند، و همچنین تجربیات واقعیت افزوده توسعه‌یافته برای موبایل‌های مجهز به واقعیت افزوده را پوشش می‌دهد. دستگاه ها

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

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

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

چگونه به آنجا برسم؟

وب غوطه ور نزدیک به یک سال است که به شکل جنینی در دسترس است. این کار از طریق WebVR 1.1 API انجام شد که از Chrome 62 به صورت آزمایشی در دسترس بوده است. این API همچنین توسط Firefox و Edge و همچنین یک polyfill برای Safari پشتیبانی می‌شود.

اما وقت آن است که ادامه دهیم.

آزمایش اولیه در 24 ژوئیه 2018 به پایان رسید و این مشخصات توسط WebXR Device API و یک آزمایش اولیه جدید جایگزین شده است.

چه اتفاقی برای WebVR 1.1 افتاد؟

ما چیزهای زیادی از WebVR 1.1 یاد گرفتیم، اما با گذشت زمان، مشخص شد که برای پشتیبانی از انواع برنامه‌هایی که توسعه‌دهندگان می‌خواهند بسازند، تغییرات عمده‌ای لازم است. فهرست کامل درس‌های آموخته‌شده خیلی طولانی است که نمی‌توان در اینجا به آن اشاره کرد، اما شامل مسائلی مانند مرتبط بودن صراحتاً API به رشته اصلی جاوا اسکریپت، فرصت‌های بسیار زیاد برای توسعه‌دهندگان برای تنظیم پیکربندی‌های آشکارا اشتباه و استفاده‌های رایج مانند پنجره جادویی است. اثر به جای یک ویژگی عمدی. (پنجره جادویی تکنیکی برای مشاهده محتوای همه جانبه بدون هدست است که در آن برنامه یک نمای واحد را بر اساس حسگر جهت گیری دستگاه ارائه می دهد.)

طراحی جدید اجرای ساده تر و بهبود عملکرد بزرگ را تسهیل می کند. در همان زمان، AR و سایر موارد استفاده در حال ظهور بودند و مهم شد که API برای پشتیبانی از موارد در آینده قابل توسعه باشد.

WebXR Device API با در نظر گرفتن این موارد استفاده گسترده طراحی و نامگذاری شده است و مسیر بهتری را به پیش می‌دهد. پیاده‌کننده‌های WebVR متعهد شده‌اند که به WebXR Device API مهاجرت کنند.

WebXR Device API چیست؟

مانند مشخصات WebVR قبل از آن، WebXR Device API محصولی از گروه Immersive Web Community است که مشارکت‌کنندگانی از Google، Microsoft، Mozilla و دیگران دارد. X در XR به عنوان نوعی متغیر جبری در نظر گرفته شده است که مخفف هر چیزی در طیف تجربیات غوطه ور است. در آزمایش اولیه ذکر شده قبلی و همچنین از طریق پلی پر در دسترس است.

وقتی این مقاله در ابتدا در دوره بتای Chrome 67 منتشر شد، فقط قابلیت‌های VR فعال بودند. واقعیت افزوده به Chrome 69 رسید. در مورد آن در واقعیت افزوده برای وب بخوانید.

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

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

چیزی که من قصد ندارم به آن بپردازم این است که چگونه محتوای AR/VR را روی صفحه بکشیم. WebXR Device API ویژگی های رندر تصویر را ارائه نمی دهد. این به شما بستگی دارد. طراحی با استفاده از WebGL API انجام می شود. اگر واقعا جاه طلب هستید می توانید این کار را انجام دهید. با این حال، توصیه می کنیم از یک چارچوب استفاده کنید. نمونه‌های وب همهجانبه از نمونه‌ای استفاده می‌کنند که فقط برای دموها به نام Cottontail ایجاد شده است. Three.js از ماه می از WebXR پشتیبانی می کند. من چیزی در مورد A-Frame نشنیده ام.

راه اندازی و اجرای یک برنامه

فرآیند اصلی این است:

  1. درخواست دستگاه XR
  2. اگر در دسترس است، یک جلسه XR درخواست کنید. اگر می خواهید کاربر گوشی خود را در یک هدست قرار دهد، به آن جلسه غوطه ور گفته می شود و برای ورود به آن نیاز به ژست کاربر دارد.
  3. از جلسه برای اجرای یک حلقه رندر استفاده کنید که 60 فریم تصویر در ثانیه ارائه می دهد. در هر فریم محتوای مناسب را روی صفحه بکشید.
  4. حلقه رندر را اجرا کنید تا زمانی که کاربر تصمیم به خروج بگیرد.
  5. جلسه XR را تمام کنید.

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

درخواست دستگاه XR

در اینجا، کد تشخیص ویژگی استاندارد را می‌شناسید. شما می توانید این را در تابعی به نام چیزی مانند checkForXR() بپیچید.

اگر از یک جلسه همهجانبه استفاده نمی کنید، می توانید از تبلیغات عملکرد و گرفتن ژست کاربر صرفنظر کنید و مستقیماً به درخواست جلسه بروید. یک جلسه همه جانبه جلسه ای است که به یک هدست نیاز دارد. یک جلسه غیر همه جانبه به سادگی محتوا را روی صفحه دستگاه نشان می دهد. وقتی به واقعیت مجازی یا واقعیت افزوده اشاره می کنید، مورد اول همان چیزی است که بیشتر مردم به آن فکر می کنند. دومی گاهی اوقات "پنجره جادویی" نامیده می شود.

if (navigator.xr) {
    navigator.xr.requestDevice()
    .then(xrDevice => {
    // Advertise the AR/VR functionality to get a user gesture.
    })
    .catch(err => {
    if (err.name === 'NotFoundError') {
        // No XRDevices available.
        console.error('No XR devices available:', err);
    } else {
        // An error occurred while requesting an XRDevice.
        console.error('Requesting XR device failed:', err);
    }
    })
} else{
    console.log("This browser does not support the WebXR API.");
}

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

اکنون که دستگاه و ژست کاربر خود را در اختیار داریم، وقت آن است که یک جلسه دریافت کنیم. برای ایجاد یک جلسه، مرورگر به یک بوم نقاشی نیاز دارد که روی آن نقاشی کند.

xrPresentationContext = htmlCanvasElement.getContext('xrpresent');
let sessionOptions = {
    // The immersive option is optional for non-immersive sessions; the value
    //   defaults to false.
    immersive: false,
    outputContext: xrPresentationContext
}
xrDevice.requestSession(sessionOptions)
.then(xrSession => {
    // Use a WebGL context as a base layer.
    xrSession.baseLayer = new XRWebGLLayer(session, gl);
    // Start the render loop
})

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

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

فرآیند اصلی برای یک حلقه رندر به این صورت است:

  1. درخواست یک قاب انیمیشن
  2. پرس و جو برای موقعیت دستگاه.
  3. محتوا را بر اساس موقعیت دستگاه به موقعیت آن بکشید.
  4. کارهای مورد نیاز برای دستگاه های ورودی را انجام دهید.
  5. این کار را 60 بار در ثانیه تکرار کنید تا زمانی که کاربر تصمیم به ترک آن بگیرد.

درخواست چارچوب ارائه

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

نوع دوم فریم، قاب ارائه است که با یک شی XRFrame نشان داده می شود. این شی حاوی اطلاعات مورد نیاز برای ارائه یک فریم از یک صحنه AR/VR به دستگاه است. این کمی گیج کننده است زیرا یک فریم ارائه با فراخوانی requestAnimationFrame() بازیابی می شود. این باعث می شود که با window.requestAnimationFrame() سازگار باشد.

قبل از اینکه چیز دیگری برای هضم به شما بدهم، کدی را ارائه خواهم کرد. نمونه زیر نحوه راه اندازی و نگهداری حلقه رندر را نشان می دهد. به استفاده دوگانه از کلمه قاب توجه کنید. و به فراخوانی بازگشتی به requestAnimationFrame() توجه کنید. این تابع 60 بار در ثانیه فراخوانی می شود.

xrSession.requestFrameOfReference('eye-level')
.then(xrFrameOfRef => {
    xrSession.requestAnimationFrame(onFrame(time, xrFrame) {
    // The time argument is for future use and not implemented at this time.
    // Process the frame.
    xrFrame.session.requestAnimationFrame(onFrame);
    }
});

ژست می گیرد

قبل از کشیدن هر چیزی روی صفحه، باید بدانید که دستگاه نمایشگر به کجا اشاره می کند و باید به صفحه نمایش دسترسی داشته باشید. به طور کلی موقعیت و جهت یک چیز در AR/VR را پوز می گویند. هم بینندگان و هم دستگاه های ورودی ژست دارند. (بعداً دستگاه‌های ورودی را پوشش می‌دهم.) هر دو حالت نمایشگر و دستگاه ورودی به‌عنوان یک ماتریس 4 در 4 تعریف می‌شوند که در یک Float32Array به ترتیب اصلی ستون‌ها ذخیره می‌شوند. با فراخوانی XRFrame.getDevicePose() روی شی قاب انیمیشن فعلی، ژست بیننده را دریافت می کنید. همیشه تست کنید تا ببینید آیا حالتی را به دست آوردید. اگر مشکلی پیش آمد، نمی خواهید روی صفحه نمایش بکشید.

let pose = xrFrame.getDevicePose(xrFrameOfRef);
if (pose) {
    // Draw something to the screen.
}

بازدیدها

پس از بررسی ژست، نوبت به کشیدن چیزی می رسد. به شیئی که به آن می کشید، view می گویند ( XRView ). اینجاست که نوع جلسه مهم می شود. نماها از شی XRFrame به عنوان یک آرایه بازیابی می شوند. اگر در یک جلسه غیر غوطه ور هستید، آرایه یک نمای دارد. اگر در یک جلسه غوطه ور هستید، آرایه دارای دو، یکی برای هر چشم است.

for (let view of xrFrame.views) {
    // Draw something to the screen.
}

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

کل حلقه رندر

اگر همه اینها را کنار هم بگذارم، کد زیر را دریافت می کنم. من یک مکان نگهدار برای دستگاه های ورودی گذاشته ام که در بخش بعدی به آن خواهم پرداخت.

xrSession.requestFrameOfReference('eye-level')
.then(xrFrameOfRef => {
    xrSession.requestAnimationFrame(onFrame(time, xrFrame) {
    // The time argument is for future use and not implemented at this time.
    let pose = xrFrame.getDevicePose(xrFrameOfRef);
    if (pose) {
        for (let view of xrFrame.views) {
        // Draw something to the screen.
        }
    }
    // Input device code will go here.
    frame.session.requestAnimationFrame(onFrame);
    }
}

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

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

xrDevice.requestSession(sessionOptions)
.then(xrSession => {
    // Create a WebGL layer and initialize the render loop.
    xrSession.addEventListener('end', onSessionEnd);
});

// Restore the page to normal after immersive access has been released.
function onSessionEnd() {
    xrSession = null;

    // Ending the session stops executing callbacks passed to the XRSession's
    // requestAnimationFrame(). To continue rendering, use the window's
    // requestAnimationFrame() function.
    window.requestAnimationFrame(onDrawFrame);
}

تعامل چگونه کار می کند؟

مانند طول عمر برنامه، من فقط می‌خواهم نحوه تعامل با اشیاء در AR یا VR را به شما بچشم.

WebXR Device API رویکرد "نقطه و کلیک" را برای ورودی کاربر اتخاذ می کند. با این رویکرد، هر منبع ورودی دارای یک پرتو اشاره گر تعریف شده برای نشان دادن جایی است که دستگاه ورودی به آن اشاره می کند و رویدادهایی برای نشان دادن زمانی که چیزی انتخاب شده است. برنامه شما اشعه اشاره گر را ترسیم می کند و نشان می دهد که در کجا قرار گرفته است. هنگامی که کاربر روی دستگاه ورودی کلیک می کند، رویدادها فعال می شوند - به طور خاص select کنید، selectStart و selectEnd . برنامه شما مشخص می کند روی چه چیزی کلیک شده است و به درستی پاسخ می دهد.

دستگاه ورودی و اشعه اشاره گر

برای کاربران، اشعه اشاره گر فقط یک خط ضعیف بین کنترلر و هر چیزی است که به آن اشاره می کنند. اما برنامه شما باید آن را ترسیم کند. این به معنای گرفتن حالت دستگاه ورودی و کشیدن یک خط از محل آن به یک شی در فضای AR/VR است. این روند تقریباً شبیه این است:

let inputSources = xrSession.getInputSources();
for (let xrInputSource of inputSources) {
    let inputPose = frame.getInputPose(inputSource, xrFrameOfRef);
    if (!inputPose) {
    continue;
    }
    if (inputPose.gripMatrix) {
    // Render a virtual version of the input device
    //   at the correct position and orientation.
    }
    if (inputPose.pointerMatrix) {
    // Draw a ray from the gripMatrix to the pointerMatrix.
    }
}

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

انتخاب آیتم ها در فضای مجازی

اشاره صرف به چیزهایی در AR/VR بسیار بی فایده است. برای انجام هر کار مفیدی، کاربران به توانایی انتخاب چیزها نیاز دارند. WebXR Device API سه رویداد را برای پاسخگویی به تعاملات کاربر فراهم می کند: select ، selectStart ، و selectEnd . آنها یک چیز عجیبی دارند که من انتظارش را نداشتم: آنها فقط به شما می گویند که یک دستگاه ورودی کلیک شده است. آنها به شما نمی گویند روی چه موردی در محیط کلیک شده است. کنترل‌کننده‌های رویداد به شی XRSession اضافه می‌شوند و باید به محض در دسترس بودن اضافه شوند.

xrDevice.requestSession(sessionOptions)
.then(xrSession => {
    // Create a WebGL layer and initialize the render loop.
    xrSession.addEventListener('selectstart', onSelectStart);
    xrSession.addEventListener('selectend', onSelectEnd);
    xrSession.addEventListener('select', onSelect);
});

این کد بر اساس یک مثال انتخاب ورودی است، در صورتی که می‌خواهید زمینه بیشتری داشته باشید.

برای اینکه بفهمید روی چه چیزی کلیک شده است از یک ژست استفاده می کنید. (آیا متعجب شدید؟ فکر نمی کردم.) جزئیات مربوط به برنامه شما یا هر فریمورکی که استفاده می کنید است و از این رو خارج از محدوده این مقاله است. رویکرد Cottontail در مثال Input Selection است.

function onSelect(ev) {
    let inputPose = ev.frame.getInputPose(ev.inputSource, xrFrameOfRef);
    if (!inputPose) {
    return;
    }
    if (inputPose.pointerMatrix) {
    // Figure out what was clicked and respond.
    }
}

نتیجه: نگاه به آینده

همانطور که قبلاً گفتم، واقعیت افزوده در کروم 69 انتظار می رود (قناری در ژوئن 2018). با این وجود، من شما را تشویق می کنم آنچه را که تا کنون به دست آورده ایم، امتحان کنید. برای بهتر کردن آن به بازخورد نیاز داریم. با تماشای ChromeStatus.com برای WebXR Hit Test ، پیشرفت آن را دنبال کنید. شما همچنین می توانید WebXR Anchors را دنبال کنید که ردیابی ژست را بهبود می بخشد.