ভার্চুয়াল বাস্তবতা ওয়েবে আসে

ভার্চুয়াল রিয়েলিটি, অগমেন্টেড রিয়েলিটি এবং এর মধ্যবর্তী সবকিছুর মতো বিভিন্ন ধরনের ইমারসিভ অভিজ্ঞতার জন্য আপনাকে প্রস্তুত করতে কয়েকটি প্রাথমিক বিষয়।

জো মেডলি
Joe Medley

ক্রোম ৭৯-এর মাধ্যমে ওয়েবে ইমারসিভ অভিজ্ঞতা এসেছে। WebXR ডিভাইস এপিআই ভার্চুয়াল রিয়েলিটি নিয়ে এসেছে, এবং ক্রোম ৮১-এ অগমেন্টেড রিয়েলিটির সাপোর্ট যুক্ত হয়েছে। অন্যদিকে, গেমপ্যাড এপিআই-এর একটি আপডেট ভিআর-এ কন্ট্রোলের উন্নত ব্যবহারকে প্রসারিত করেছে। ফায়ারফক্স রিয়েলিটি, অকুলাস ব্রাউজার, এজ এবং ম্যাজিক লিপের হেলিও ব্রাউজারসহ অন্যান্য ব্রাউজারগুলোও শীঘ্রই এই স্পেসিফিকেশনগুলো সাপোর্ট করবে।

এই নিবন্ধটি ইমার্সিভ ওয়েবের উপর একটি ধারাবাহিক আলোচনার সূচনা করছে। এই পর্বে একটি সাধারণ WebXR অ্যাপ্লিকেশন সেট আপ করা এবং একটি XR সেশনে প্রবেশ ও প্রস্থান করার পদ্ধতি আলোচনা করা হয়েছে। পরবর্তী নিবন্ধগুলিতে ফ্রেম লুপ (WebXR অভিজ্ঞতার মূল চালিকাশক্তি), অগমেন্টেড রিয়েলিটির খুঁটিনাটি এবং WebXR হিট টেস্ট এপিআই (একটি AR সেশনে পৃষ্ঠতল শনাক্ত করার উপায়) নিয়ে আলোচনা করা হবে। অন্যথা উল্লেখ না থাকলে, এই এবং পরবর্তী নিবন্ধগুলিতে আমি যা কিছু আলোচনা করব, তা AR এবং VR উভয়ের ক্ষেত্রেই সমানভাবে প্রযোজ্য।

ইমারসিভ ওয়েব বলতে কী বোঝায়?

যদিও আমরা ইমার্সিভ অভিজ্ঞতা বর্ণনা করতে দুটি পরিভাষা ব্যবহার করি—অগমেন্টেড রিয়েলিটি এবং ভার্চুয়াল রিয়েলিটি—অনেকেই এটিকে সম্পূর্ণ বাস্তবতা থেকে সম্পূর্ণ ভার্চুয়াল পর্যন্ত একটি বর্ণালীর অংশ হিসেবে বিবেচনা করেন, যার মাঝে নিমজ্জনের বিভিন্ন মাত্রা থাকে। XR-এর 'X' অক্ষরটি সেই চিন্তাভাবনাকে প্রতিফলিত করার উদ্দেশ্যে ব্যবহৃত হয়; এটি এক ধরনের বীজগাণিতিক চলক যা ইমার্সিভ অভিজ্ঞতার এই বর্ণালীর যেকোনো কিছুকে বোঝায়।

একটি গ্রাফ যা সম্পূর্ণ বাস্তবতা থেকে সম্পূর্ণ নিমগ্নতা পর্যন্ত চাক্ষুষ অভিজ্ঞতার পরিসরকে চিত্রিত করে।
নিমগ্ন অভিজ্ঞতার বর্ণালী

ইমার্সিভ অভিজ্ঞতার উদাহরণগুলির মধ্যে রয়েছে:

  • খেলা
  • ৩৬০° ভিডিও
  • নিমগ্ন পরিবেশে উপস্থাপিত ঐতিহ্যবাহী ২ডি (বা ৩ডি) ভিডিও
  • বাড়ি কেনা
  • কেনার আগে আপনার বাড়িতে পণ্যগুলো দেখে নেওয়া
  • ইমার্সিভ আর্ট
  • এমন একটা দারুণ জিনিস যা এখনো কেউ ভাবেনি।

ধারণা এবং ব্যবহার

আমি WebXR ডিভাইস এপিআই ব্যবহারের কিছু প্রাথমিক বিষয় ব্যাখ্যা করব। আমার দেওয়া তথ্যের চেয়ে যদি আপনার আরও গভীর জ্ঞানের প্রয়োজন হয়, তবে ইমারসিভ ওয়েব ওয়ার্কিং গ্রুপের WebXR স্যাম্পলগুলো অথবা MDN-এর ক্রমবর্ধমান রেফারেন্স সামগ্রীগুলো দেখতে পারেন। আপনি যদি WebXR ডিভাইস এপিআই-এর পুরোনো সংস্করণগুলোর সাথে পরিচিত হন, তবে এই সমস্ত বিষয়বস্তু একবার চোখ বুলিয়ে নিলেই চলবে। এতে কিছু পরিবর্তন এসেছে।

এই আর্টিকেলের কোডটি ইমারসিভ ওয়েব ওয়ার্কিং গ্রুপের বেয়ারবোনস স্যাম্পল ( ডেমো , সোর্স )-এর উপর ভিত্তি করে তৈরি, তবে স্পষ্টতা ও সরলতার জন্য এটিকে সম্পাদনা করা হয়েছে।

WebXR স্পেসিফিকেশন তৈরির একটি অংশ হলো ব্যবহারকারীদের সুরক্ষার জন্য নিরাপত্তা ও গোপনীয়তার ব্যবস্থাগুলোকে বিশদভাবে তৈরি করা। ফলস্বরূপ, এর বাস্তবায়নগুলোকে অবশ্যই কিছু নির্দিষ্ট আবশ্যকতা মেনে চলতে হয়। কোনো ওয়েব পেজ বা অ্যাপ দর্শকের কাছ থেকে কোনো সংবেদনশীল তথ্য অনুরোধ করার আগে সেটিকে অবশ্যই সক্রিয় এবং ফোকাসড থাকতে হবে। ওয়েব পেজ বা অ্যাপ অবশ্যই HTTPS-এর মাধ্যমে পরিবেশন করতে হবে। এপিআই-টি নিজেই সেন্সর এবং ক্যামেরা থেকে প্রাপ্ত তথ্য সুরক্ষিত করার জন্য ডিজাইন করা হয়েছে, যা এর কার্যকারিতার জন্য প্রয়োজন।

একটি সেশনের জন্য অনুরোধ করুন

একটি XR সেশনে প্রবেশ করার জন্য ব্যবহারকারীর একটি অঙ্গভঙ্গি প্রয়োজন। সেটি করার জন্য, ফিচার ডিটেকশন ব্যবহার করে XRSystem এর উপস্থিতি পরীক্ষা করুন ( navigator.xr এর মাধ্যমে) এবং XRSystem.isSessionSupported() কল করুন। মনে রাখবেন যে, Chrome-এর ৭৯ এবং ৮০ সংস্করণে 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 ইনস্ট্যান্সে যায়। এপিআই-এর প্রথম দিকের সংস্করণগুলিতে, একটি স্ক্রিপ্টকে সেশনের জন্য অনুরোধ করার আগে একটি ডিভাইসের জন্য অনুরোধ করতে হতো। এখন, ডিভাইসটি স্বয়ংক্রিয়ভাবে অর্জিত হয়ে যায়।

একটি সেশনে প্রবেশ করুন

একটি সেশন পাওয়ার পর, আমাকে সেটি চালু করে তাতে প্রবেশ করতে হবে। কিন্তু তার আগে, আমাকে কয়েকটি বিষয় সেট আপ করতে হবে। একটি সেশনের জন্য একটি onend ' ইভেন্ট হ্যান্ডলার প্রয়োজন, যাতে ব্যবহারকারী বেরিয়ে গেলে অ্যাপ বা ওয়েব পেজটি রিসেট হয়ে যায়।

আমার দৃশ্যটি আঁকার জন্য একটি <canvas> এলিমেন্টেরও প্রয়োজন হবে। এটিকে একটি XR-উপযোগী WebGLRenderingContext বা WebGL2RenderingContext হতে হবে। সমস্ত অঙ্কনের কাজ এগুলি অথবা Three.js-এর মতো কোনো WebGL-ভিত্তিক ফ্রেমওয়ার্ক ব্যবহার করে করা হয়।

এখন যেহেতু আমার আঁকার জন্য একটি জায়গা আছে, তাই এর উপর আঁকার জন্য আমার একটি কন্টেন্ট সোর্স প্রয়োজন। এর জন্য, আমি XRWebGLLayer এর একটি ইনস্ট্যান্স তৈরি করি। আমি XRSession.updateRenderState() কল করে এটিকে ক্যানভাসের সাথে যুক্ত করি।

একবার কোনো সেশনে প্রবেশ করলে, ভার্চুয়াল রিয়েলিটিতে জিনিসপত্র কোথায় আছে তা নির্ধারণ করার জন্য আমার একটি উপায় প্রয়োজন। এর জন্য আমার একটি রেফারেন্স স্পেস লাগবে। একটি 'local-floor' রেফারেন্স স্পেস হলো এমন একটি স্থান, যেখানে মূলবিন্দু দর্শকের কাছাকাছি অবস্থিত থাকে এবং y-অক্ষ মেঝের স্তরে ০ হয় ও এর স্থান পরিবর্তন হওয়ার কথা নয়। অন্যান্য ধরনের রেফারেন্স স্পেসও আছে, কিন্তু সেটি এত জটিল একটি বিষয় যে এখানে আমি তা নিয়ে বিস্তারিত আলোচনা করতে পারব না। আমি রেফারেন্স স্পেসটি একটি ভেরিয়েবলে সংরক্ষণ করি, কারণ স্ক্রিনে আঁকার সময় আমার এটি প্রয়োজন হবে।

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() কল করি। এটি ভার্চুয়াল কন্টেন্ট উপস্থাপনের সূচনা, যা ফ্রেম লুপের মধ্যে সম্পন্ন হয়।

একটি ফ্রেম লুপ চালান

ফ্রেম লুপ হলো ইউজার-এজেন্ট দ্বারা নিয়ন্ত্রিত একটি অসীম লুপ, যেখানে স্ক্রিনে বারবার কন্টেন্ট আঁকা হয়। কন্টেন্ট ফ্রেম নামক বিচ্ছিন্ন ব্লকে আঁকা হয়। ফ্রেমগুলোর এই ধারাবাহিকতা গতির একটি বিভ্রম তৈরি করে। ভিআর অ্যাপ্লিকেশনের জন্য প্রতি সেকেন্ডে ফ্রেমের সংখ্যা ৬০ থেকে ১৪৪ পর্যন্ত হতে পারে। অ্যান্ড্রয়েডের জন্য এআর প্রতি সেকেন্ডে ৩০ ফ্রেমে চলে। আপনার কোডে কোনো নির্দিষ্ট ফ্রেম রেট ধরে নেওয়া উচিত নয়।

ফ্রেম লুপের মূল প্রক্রিয়াটি হলো:

  1. XRSession.requestAnimationFrame() কল করুন। এর জবাবে, ইউজার এজেন্ট আপনার দ্বারা সংজ্ঞায়িত XRFrameRequestCallback কে আহ্বান করে।
  2. আপনার কলব্যাক ফাংশনের ভিতরে:
    1. আবার XRSession.requestAnimationFrame() কল করুন।
    2. দর্শকের ভঙ্গিটি বুঝুন।
    3. XRWebGLLayer থেকে WebGLFramebuffer টি WebGLRenderingContext এ পাস ('bind') করুন।
    4. প্রতিটি XRView অবজেক্টের উপর পুনরাবৃত্তি করুন, XRWebGLLayer থেকে এর XRViewport পুনরুদ্ধার করুন এবং সেটি WebGLRenderingContext এ প্রেরণ করুন।
    5. ফ্রেমবাফারে কিছু আঁকুন।

এই নিবন্ধের বাকি অংশে ধাপ ১ এবং ধাপ ২-এর অংশবিশেষ, অর্থাৎ XRFrameRequestCallback সেট আপ করা ও কল করার বর্ণনা দেওয়া হয়েছে। ধাপ ২-এর বাকি বিষয়গুলো দ্বিতীয় ভাগে আলোচনা করা হয়েছে।

XRFrameRequestCallback

XRFrameRequestCallback টি আপনার দ্বারা সংজ্ঞায়িত করা হয়। এটি দুটি প্যারামিটার গ্রহণ করে: একটি DOMHighResTimeStamp এবং একটি XRFrame ইনস্ট্যান্স। XRFrame অবজেক্টটি ডিসপ্লেতে একটি একক ফ্রেম রেন্ডার করার জন্য প্রয়োজনীয় তথ্য সরবরাহ করে। DOMHighResTimeStamp আর্গুমেন্টটি ভবিষ্যতের ব্যবহারের জন্য।

অন্য কিছু করার আগে, আমি পরবর্তী অ্যানিমেশন ফ্রেমের জন্য অনুরোধ করব। পূর্বেই যেমন বলা হয়েছে, ফ্রেমের সময় ব্যবহারকারী এজেন্ট দ্বারা অন্তর্নিহিত হার্ডওয়্যারের উপর ভিত্তি করে নির্ধারিত হয়। প্রথমে পরবর্তী ফ্রেমের জন্য অনুরোধ করা নিশ্চিত করে যে, কলব্যাকের সময় কোনো ত্রুটি ঘটলেও ফ্রেম লুপটি চলতে থাকবে।

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

এই পর্যায়ে, দর্শকের জন্য কিছু আঁকার সময় হয়েছে। সেটা দ্বিতীয় পর্বের আলোচনা। সেখানে যাওয়ার আগে, চলুন দেখে নিই কীভাবে একটি সেশন শেষ করতে হয়।

সেশন শেষ করুন

একটি ইমারসিভ সেশন বিভিন্ন কারণে শেষ হতে পারে, যার মধ্যে একটি হলো আপনার নিজের কোড থেকে XRSession.end() কল করে সেশনটি বন্ধ করা। অন্যান্য কারণগুলোর মধ্যে রয়েছে হেডসেটের সংযোগ বিচ্ছিন্ন হওয়া অথবা অন্য কোনো অ্যাপ্লিকেশনের এর নিয়ন্ত্রণ নিয়ে নেওয়া। এই কারণেই একটি সুশৃঙ্খল অ্যাপ্লিকেশনের উচিত ' end ইভেন্টটি পর্যবেক্ষণ করা। যখন এটি ঘটে, তখন সেশনটি এবং এর সাথে সম্পর্কিত রেন্ডার অবজেক্টগুলো বাতিল করে দেওয়া উচিত। একটি শেষ হয়ে যাওয়া ইমারসিভ সেশন পুনরায় চালু করা যায় না। ইমারসিভ অভিজ্ঞতায় পুনরায় প্রবেশ করতে, আমার অ্যাপটিকে একটি নতুন সেশন শুরু করতে হবে।

সেশনে প্রবেশ করার সময় মনে করুন যে, সেটআপের সময় আমি একটি onend ইভেন্ট হ্যান্ডলার যোগ করেছিলাম।

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

ইভেন্ট হ্যান্ডলারের ভিতরে, ব্যবহারকারী সেশনে প্রবেশ করার আগের অ্যাপের অবস্থাটি পুনরুদ্ধার করুন।

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

উপসংহার

একটি ওয়েব এক্সআর বা এআর অ্যাপ্লিকেশন লেখার জন্য প্রয়োজনীয় সবকিছু আমি ব্যাখ্যা করিনি। আশা করি, কোডটি নিজে থেকে বুঝতে শুরু করার জন্য এবং পরীক্ষা-নিরীক্ষা শুরু করার জন্য আমি আপনাকে যথেষ্ট তথ্য দিয়েছি। পরবর্তী আর্টিকেলে, আমি ফ্রেম লুপ ব্যাখ্যা করব, যেখানে স্ক্রিনে কন্টেন্ট আঁকা হয়।