ভার্চুয়াল বাস্তবতা ওয়েবে আসে, দ্বিতীয় অংশ

ফ্রেম লুপ সম্পর্কে সব

জো মেডলি
Joe Medley

সম্প্রতি, আমি প্রকাশ করেছি ভার্চুয়াল রিয়েলিটি ওয়েবে আসে , একটি নিবন্ধ যা WebXR ডিভাইস API-এর পিছনে মৌলিক ধারণাগুলি প্রবর্তন করে। আমি XR সেশনের অনুরোধ, প্রবেশ এবং শেষ করার জন্য নির্দেশনাও দিয়েছি।

এই নিবন্ধটি ফ্রেম লুপ বর্ণনা করে, যা একটি ব্যবহারকারী-এজেন্ট নিয়ন্ত্রিত অসীম লুপ যাতে বিষয়বস্তু বারবার পর্দায় আঁকা হয়। বিষয়বস্তু ফ্রেম নামক পৃথক ব্লকে আঁকা হয়। ফ্রেমের উত্তরাধিকার আন্দোলনের বিভ্রম তৈরি করে।

WebGL এবং WebGL2 হল WebXR অ্যাপে ফ্রেম লুপের সময় সামগ্রী রেন্ডার করার একমাত্র মাধ্যম। সৌভাগ্যবশত অনেক ফ্রেমওয়ার্ক WebGL এবং WebGL2 এর উপরে বিমূর্ততার একটি স্তর প্রদান করে। এই ধরনের ফ্রেমওয়ার্কের মধ্যে three.js , babylonjs এবং PlayCanvas অন্তর্ভুক্ত রয়েছে, যেখানে A-Frame এবং React 360 ডিজাইন করা হয়েছে WebXR-এর সাথে ইন্টারঅ্যাক্ট করার জন্য।

এই নিবন্ধটি একটি WebGL বা একটি ফ্রেমওয়ার্ক টিউটোরিয়াল নয়৷ এটি ইমারসিভ ওয়েব ওয়ার্কিং গ্রুপের ইমারসিভ ভিআর সেশন নমুনা ( ডেমো , উত্স ) ব্যবহার করে একটি ফ্রেম লুপের মূল বিষয়গুলি ব্যাখ্যা করে৷ আপনি যদি WebGL বা ফ্রেমওয়ার্কগুলির মধ্যে একটিতে ডুব দিতে চান, ইন্টারনেট নিবন্ধগুলির একটি ক্রমবর্ধমান তালিকা প্রদান করে৷

খেলোয়াড় এবং খেলা

ফ্রেম লুপ বোঝার চেষ্টা করার সময়, আমি বিশদে হারিয়ে যেতে থাকি। খেলার মধ্যে অনেক বস্তু আছে, এবং তাদের কিছু শুধুমাত্র অন্যান্য বস্তুর রেফারেন্স বৈশিষ্ট্য দ্বারা নামকরণ করা হয়. আপনাকে এটি সোজা রাখতে সাহায্য করার জন্য, আমি বস্তুগুলি বর্ণনা করব, যাকে আমি 'খেলোয়াড়' বলছি। তারপর আমি বর্ণনা করব কিভাবে তারা ইন্টারঅ্যাক্ট করে, যাকে আমি 'গেম' বলছি।

খেলোয়াড়দের

XRViewerPose

একটি ভঙ্গি হল 3D স্পেসে কোন কিছুর অবস্থান এবং অভিযোজন। দর্শক এবং ইনপুট ডিভাইস উভয়েরই একটি ভঙ্গি আছে, কিন্তু এটি দর্শকের ভঙ্গি যা আমরা এখানে নিয়ে চিন্তিত। ভিউয়ার এবং ইনপুট ডিভাইস উভয় ভঙ্গিতেই একটি transform বৈশিষ্ট্য রয়েছে যা একটি ভেক্টর হিসাবে এর অবস্থান এবং উত্সের সাথে সম্পর্কিত একটি চতুর্ভুজ হিসাবে এর অভিযোজন বর্ণনা করে। XRSession.requestReferenceSpace() কল করার সময় অনুরোধ করা রেফারেন্স স্পেস টাইপের উপর ভিত্তি করে মূলটি নির্দিষ্ট করা হয়।

রেফারেন্স স্পেস ব্যাখ্যা করতে একটু লাগে. আমি অগমেন্টেড রিয়েলিটির গভীরতায় সেগুলো কভার করি। এই নিবন্ধটির ভিত্তি হিসাবে আমি যে নমুনাটি ব্যবহার করছি সেটি একটি 'local' রেফারেন্স স্পেস ব্যবহার করে যার অর্থ হল একটি সুনির্দিষ্ট ফ্লোর ছাড়াই সেশন তৈরির সময় দর্শকের অবস্থানে রয়েছে এবং এর সুনির্দিষ্ট অবস্থান প্ল্যাটফর্ম অনুসারে পরিবর্তিত হতে পারে।

এক্সআরভিউ

একটি দৃশ্য ভার্চুয়াল দৃশ্য দেখার একটি ক্যামেরার সাথে মিলে যায়। একটি ভিউতে একটি transform বৈশিষ্ট্যও রয়েছে যা একটি ভেক্টর হিসাবে এটির অবস্থান এবং তার অভিযোজন বর্ণনা করে। এগুলি ভেক্টর/কোয়াটারনিয়ন জোড়া এবং সমতুল্য ম্যাট্রিক্স হিসাবে উভয়ই সরবরাহ করা হয়, আপনার কোডের সাথে কোনটি সবচেয়ে উপযুক্ত তার উপর নির্ভর করে আপনি উপস্থাপনা ব্যবহার করতে পারেন। প্রতিটি দৃশ্য দর্শকের কাছে চিত্র উপস্থাপনের জন্য একটি ডিভাইস দ্বারা ব্যবহৃত একটি প্রদর্শন বা প্রদর্শনের একটি অংশের সাথে মিলে যায়। XRView অবজেক্টগুলি XRViewerPose অবজেক্ট থেকে একটি অ্যারেতে ফেরত দেওয়া হয়। অ্যারের ভিউ সংখ্যা পরিবর্তিত হয়. মোবাইল ডিভাইসে একটি AR দৃশ্যের একটি দৃশ্য থাকে, যা ডিভাইসের স্ক্রীনকে কভার করতে পারে বা নাও পারে। হেডসেটগুলিতে সাধারণত দুটি দৃশ্য থাকে, প্রতিটি চোখের জন্য একটি।

XRWebGLLayer

স্তরগুলি বিটম্যাপ চিত্রগুলির একটি উত্স এবং সেই চিত্রগুলিকে ডিভাইসে কীভাবে রেন্ডার করা হবে তার বর্ণনা প্রদান করে৷ এই বিবরণটি এই প্লেয়ার যা করে তা পুরোপুরি ক্যাপচার করে না। আমি এটিকে একটি ডিভাইস এবং একটি WebGLRenderingContext মধ্যে একজন মধ্যস্থতাকারী হিসাবে ভাবতে এসেছি। MDN অনেকটা একই দৃষ্টিভঙ্গি গ্রহণ করে, উল্লেখ করে যে এটি দুটির মধ্যে 'একটি সংযোগ প্রদান করে'। যেমন, এটি অন্যান্য খেলোয়াড়দের অ্যাক্সেস প্রদান করে।

সাধারণভাবে, WebGL অবজেক্ট 2D এবং 3D গ্রাফিক্স রেন্ডার করার জন্য রাষ্ট্রীয় তথ্য সঞ্চয় করে।

WebGLFramebuffer

একটি ফ্রেমবাফার WebGLRenderingContext কে ইমেজ ডেটা প্রদান করে। XRWebGLLayer থেকে এটি পুনরুদ্ধার করার পরে, আপনি এটিকে বর্তমান WebGLRenderingContext এ পাস করুন। bindFramebuffer() কল করা ব্যতীত (এটি সম্পর্কে আরও পরে) আপনি কখনই এই বস্তুটি সরাসরি অ্যাক্সেস করতে পারবেন না। আপনি এটি শুধুমাত্র XRWebGLLayer থেকে WebGLRenderingContext-এ পাস করবেন।

এক্সআরভিউপোর্ট

একটি ভিউপোর্ট WebGLFramebuffer এ একটি আয়তক্ষেত্রাকার অঞ্চলের স্থানাঙ্ক এবং মাত্রা প্রদান করে।

WebGLRendering Context

একটি রেন্ডারিং প্রসঙ্গ একটি ক্যানভাসের জন্য একটি প্রোগ্রাম্যাটিক অ্যাক্সেস পয়েন্ট (আমরা যে স্থানটি আঁকছি)। এটি করার জন্য, এটির একটি WebGLFramebuffer এবং একটি XRViewport উভয়ই প্রয়োজন৷

XRWebGLLayer এবং WebGLRenderingContext মধ্যে সম্পর্ক লক্ষ্য করুন। একটি দর্শকের ডিভাইসের সাথে মিলে যায় এবং অন্যটি ওয়েব পৃষ্ঠার সাথে মিলে যায়। WebGLFramebuffer এবং XRViewport পূর্ববর্তী থেকে পরবর্তীতে পাস করা হয়।

XRWebGLLayer এবং WebGLRenderingContext এর মধ্যে সম্পর্ক
XRWebGLLayer এবং WebGLRenderingContext এর মধ্যে সম্পর্ক

খেলা

এখন যেহেতু আমরা জানি খেলোয়াড় কারা, চলুন দেখে নেওয়া যাক তারা কী খেলা খেলে। এটি এমন একটি খেলা যা প্রতিটি ফ্রেমের সাথে শুরু হয়। মনে রাখবেন যে ফ্রেমগুলি একটি ফ্রেম লুপের অংশ যা এমন হারে ঘটে যা অন্তর্নিহিত হার্ডওয়্যারের উপর নির্ভর করে। VR অ্যাপ্লিকেশনের জন্য প্রতি সেকেন্ডে ফ্রেম 60 থেকে 144 পর্যন্ত হতে পারে। Android এর জন্য AR প্রতি সেকেন্ডে 30 ফ্রেমে চলে। আপনার কোড কোন নির্দিষ্ট ফ্রেম হার অনুমান করা উচিত নয়.

ফ্রেম লুপের জন্য মৌলিক প্রক্রিয়া এই মত দেখায়:

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

যেহেতু ধাপ 1 এবং 2a পূর্ববর্তী নিবন্ধে কভার করা হয়েছিল, আমি ধাপ 2b থেকে শুরু করব।

দর্শকের ভঙ্গি পান

এটা সম্ভবত বলা ছাড়া যায়. AR বা VR-এ যেকোন কিছু আঁকতে হলে দর্শক কোথায় এবং তারা কোথায় খুঁজছে তা জানতে হবে। দর্শকের অবস্থান এবং অভিযোজন একটি XRViewerPose অবজেক্ট দ্বারা প্রদান করা হয়। আমি বর্তমান অ্যানিমেশন ফ্রেমে XRFrame.getViewerPose() কল করে দর্শকের ভঙ্গি পেয়েছি। আমি সেশন সেট আপ করার সময় আমি অর্জিত রেফারেন্স স্পেসটি পাস করি। এই বস্তুর দ্বারা প্রত্যাবর্তিত মানগুলি সর্বদা আমি বর্তমান সেশনে প্রবেশ করার সময় যে রেফারেন্স স্পেসের অনুরোধ করেছিলাম তার সাথে সম্পর্কিত। আপনি মনে করতে পারেন, পোজ অনুরোধ করার সময় আমাকে বর্তমান রেফারেন্স স্পেস পাস করতে হবে।

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

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

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

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

একটি সংক্ষিপ্ত পথচলা

পরবর্তী ধাপে সেশন সেট-আপের সময় তৈরি করা বস্তুর প্রয়োজন। মনে রাখবেন যে আমি একটি ক্যানভাস তৈরি করেছি এবং এটিকে একটি XR- সামঞ্জস্যপূর্ণ ওয়েব GL রেন্ডারিং প্রসঙ্গ তৈরি করার নির্দেশ দিয়েছি, যা আমি canvas.getContext() কল করে পেয়েছি। সমস্ত অঙ্কন WebGL API, WebGL2 API, বা WebGL-ভিত্তিক ফ্রেমওয়ার্ক যেমন Three.js ব্যবহার করে করা হয়। XRWebGLLayer এর একটি নতুন উদাহরণ সহ updateRenderState() মাধ্যমে এই প্রসঙ্গটি সেশন অবজেক্টে পাঠানো হয়েছিল।

let canvas = document.createElement('canvas');
// The rendering context must be based on WebGL or WebGL2
let webGLRenContext = canvas.getContext('webgl', { xrCompatible: true });
xrSession.updateRenderState({
    baseLayer: new XRWebGLLayer(xrSession, webGLRenContext)
  });

WebGLFramebuffer পাস ('বাইন্ড') করুন

XRWebGLLayer WebGLRenderingContext এর জন্য একটি ফ্রেমবাফার প্রদান করে যা বিশেষভাবে WebXR-এর সাথে ব্যবহারের জন্য এবং রেন্ডারিং কনটেক্সট ডিফল্ট ফ্রেমবাফার প্রতিস্থাপনের জন্য প্রদান করে। একে WebGL এর ভাষায় 'বাইন্ডিং' বলা হয়।

function onXRFrame(hrTime, xrFrame) {
  let xrSession = xrFrame.session;
  xrSession.requestAnimationFrame(onXRFrame);
  let xrViewerPose = xrFrame.getViewerPose(xrRefSpace);
  if (xrViewerPose) {
    let glLayer = xrSession.renderState.baseLayer;
    webGLRenContext.bindFramebuffer(webGLRenContext.FRAMEBUFFER, glLayer.framebuffer);
    // Iterate over the views
  }
}

প্রতিটি XRView অবজেক্টের উপর পুনরাবৃত্তি করুন

ভঙ্গি পাওয়ার পরে এবং ফ্রেমবাফার বাঁধাই করার পরে, এটি ভিউপোর্টগুলি পাওয়ার সময়। XRViewerPose এ XRView ইন্টারফেসের একটি অ্যারে রয়েছে যার প্রতিটি একটি প্রদর্শন বা প্রদর্শনের একটি অংশকে উপস্থাপন করে। তারা এমন তথ্য ধারণ করে যা ডিভাইস এবং দর্শকের জন্য সঠিকভাবে অবস্থান করে এমন বিষয়বস্তু রেন্ডার করার জন্য প্রয়োজনীয়, যেমন দেখার ক্ষেত্র, চোখের অফসেট এবং অন্যান্য অপটিক্যাল বৈশিষ্ট্য। যেহেতু আমি দুটি চোখের জন্য আঁকছি, আমার দুটি দৃষ্টিভঙ্গি আছে, যা আমি লুপ করি এবং প্রতিটির জন্য একটি পৃথক চিত্র আঁকি।

ফোন-ভিত্তিক অগমেন্টেড রিয়েলিটির জন্য বাস্তবায়ন করার সময়, আমার শুধুমাত্র একটি দৃশ্য থাকবে কিন্তু আমি এখনও একটি লুপ ব্যবহার করব। যদিও এটি একটি দৃশ্যের মাধ্যমে পুনরাবৃত্তি করা অর্থহীন বলে মনে হতে পারে, এটি করার ফলে আপনি নিমগ্ন অভিজ্ঞতার বর্ণালীর জন্য একটি একক রেন্ডারিং পাথ পেতে পারেন৷ এটি WebXR এবং অন্যান্য নিমজ্জিত সিস্টেমের মধ্যে একটি গুরুত্বপূর্ণ পার্থক্য।

function onXRFrame(hrTime, xrFrame) {
  let xrSession = xrFrame.session;
  xrSession.requestAnimationFrame(onXRFrame);
  let xrViewerPose = xrFrame.getViewerPose(xrRefSpace);
  if (xrViewerPose) {
    let glLayer = xrSession.renderState.baseLayer;
    webGLRenContext.bindFramebuffer(webGLRenContext.FRAMEBUFFER, glLayer.framebuffer);
    for (let xrView of xrViewerPose.views) {
      // Pass viewports to the context
    }
  }
}

XRViewport অবজেক্টটিকে WebGLRenderingContext-এ পাস করুন

একটি XRView অবজেক্ট একটি স্ক্রিনে যা পর্যবেক্ষণযোগ্য তা বোঝায়। কিন্তু সেই দৃশ্যে আঁকতে আমার যন্ত্রের জন্য নির্দিষ্ট স্থানাঙ্ক এবং মাত্রা প্রয়োজন। ফ্রেমবাফারের মতো, আমি XRWebGLLayer থেকে তাদের অনুরোধ করছি এবং WebGLRenderingContext এ পাঠাচ্ছি।

function onXRFrame(hrTime, xrFrame) {
  let xrSession = xrFrame.session;
  xrSession.requestAnimationFrame(onXRFrame);
  let xrViewerPose = xrFrame.getViewerPose(xrRefSpace);
  if (xrViewerPose) {
    let glLayer = xrSession.renderState.baseLayer;
    webGLRenContext.bindFramebuffer(webGLRenContext.FRAMEBUFFER, glLayer.framebuffer);
    for (let xrView of xrViewerPose.views) {
      let viewport = glLayer.getViewport(xrView);
      webGLRenContext.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
      // Draw something to the framebuffer
    }
  }
}

WebGLRenContext

এই নিবন্ধটি লেখার সময় আমি webGLRenContext অবজেক্টের নামকরণ নিয়ে কয়েকজন সহকর্মীর সাথে বিতর্ক করেছি। নমুনা স্ক্রিপ্ট এবং বেশিরভাগ WebXR কোড সহজে এই পরিবর্তনশীলটিকে gl বলে। যখন আমি নমুনাগুলি বোঝার জন্য কাজ করছিলাম, তখন আমি ভুলে গেছি যে gl কী উল্লেখ করেছে। আমি এটাকে বলেছি webGLRenContext আপনার শেখার সময় মনে করিয়ে দেওয়ার জন্য যে এটি WebGLRenderingContext এর একটি উদাহরণ।

কারণ হল যে gl ব্যবহার করা পদ্ধতির নামগুলিকে OpenGL ES 2.0 API-তে তাদের সমকক্ষের মতো দেখতে দেয়, যা সংকলিত ভাষায় VR তৈরির জন্য ব্যবহৃত হয়। আপনি যদি OpenGL ব্যবহার করে VR অ্যাপ লিখে থাকেন তাহলে এই সত্যটি সুস্পষ্ট, কিন্তু আপনি যদি এই প্রযুক্তিতে সম্পূর্ণ নতুন হন তাহলে বিভ্রান্তিকর।

ফ্রেমবাফারে কিছু আঁকুন

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

উপসংহার

এখানেই WebXR আপডেট বা নিবন্ধের শেষ নেই। আপনি MDN-এ WebXR-এর সমস্ত ইন্টারফেস এবং সদস্যদের জন্য একটি রেফারেন্স খুঁজে পেতে পারেন। ইন্টারফেসে আসন্ন উন্নতির জন্য, Chrome স্থিতিতে পৃথক বৈশিষ্ট্যগুলি অনুসরণ করুন।

আনস্প্ল্যাশে JESHOOTS.COM এর ছবি