WebGPU ক্যানভাসে HTML

WebGPU ক্যানভাসের মধ্যে HTML রেন্ডার করলে, WebGL ক্যানভাসে HTML রেন্ডার করার মতোই সব সুবিধা পাওয়া যায়, যেমন DOM-এ শেডার এফেক্ট প্রয়োগ করা বা 3D দৃশ্যে ইন্টার‍্যাক্টিভ HTML ইন্টিগ্রেট করা। তবে, WebGL-এর তুলনায় WebGPU অনেক বেশি সুবিধা অফার করে।

এই নির্দেশিকা দেখায় যে কীভাবে HTML-কে WebGPU ক্যানভাসে রেন্ডার করতে হয়। API ওভারভিউতে HTML-ইন-Canvas সম্পর্কে আরও জানুন।

WebGPU ক্যানভাসে HTML রেন্ডার করার জন্য নিম্নলিখিত ধাপগুলি প্রয়োজন:

  1. আপনার ক্যানভাস প্রস্তুত করুন। ব্রাউজারকে জানানোর জন্য সঠিক অ্যাট্রিবিউট সেট করুন যাতে এটি ক্যানভাসে HTML রেন্ডার করতে পারে। এই সেট-আপ 2D, WebGL ও WebGPU কন্টেক্সট জুড়ে একই রকম। কীভাবে আপনার ক্যানভাস সেট-আপ করবেন এবং কীভাবে স্বতন্ত্রভাবে আঁকার জন্য HTML এলিমেন্ট ঘোষণা করবেন তা জানুন।
  2. টেক্সচার হিসেবে HTML প্রয়োগ করুন:
    1. GPU টেক্সচার স্টোরেজ আগে থেকে বরাদ্দ করুন।
    2. টেক্সচার হিসেবে DOM স্ন্যাপশট আপলোড করুন।
  3. DOM ও পিক্সেল সিঙ্ক করুন।

WebGPU টেক্সচার হিসেবে HTML এলিমেন্ট আঁকা

WebGPU-তে, drawElementImageToTexture() ব্যবহার করে HTML এলিমেন্ট GPU-তে 2D টেক্সচার হিসেবে আপলোড করা হয়।

টেক্সচার স্টোরেজ আগে থেকে বরাদ্দ করুন

WebGPU-এর জন্য এক্সপ্লিসিট মেমরি অ্যালোকেশন প্রয়োজন। টেক্সচারে DOM পিক্সেল কপি করার আগে, আপনাকে অবশ্যই device.createTexture() পদ্ধতি ব্যবহার করে GPU VRAM রিজার্ভ করতে হবে:

const context = canvas.getContext("webgpu");

// Pre-allocate the texture size as needed
// For example: HTML element CSS size × devicePixelRatio
const size = canvas.getElementImageDefaultSize(myElement);
const myElementWidth = Math.ceil(size.width);
const myElementHeight = Math.ceil(size.height);

// Pre-allocate the GPUTexture backing (run once during setup)
const myTexture = device.createTexture({
  size: {
    width: myElementWidth,
    height: myElementHeight,
    depthOrArrayLayers: 1, // optional (defaults to 1)
  },
  format: "rgba8unorm",
  usage:
    GPUTextureUsage.TEXTURE_BINDING |
    GPUTextureUsage.COPY_DST |
    GPUTextureUsage.RENDER_ATTACHMENT,
});

HTML এলিমেন্ট ছবি আঁকুন

WebGPU-তে, drawElementImageToTexture() পদ্ধতি HTML এলিমেন্টের স্ন্যাপশট ড্র করে। এই পদ্ধতিতে দুটি ডিকশনারি অবজেক্ট ব্যবহার করা হয়: source এবং destination।

source রাস্টারাইজ করার জন্য সোর্স DOM এলিমেন্ট এবং ঐচ্ছিক সাব-রেকট্যাঙ্গেল ক্লিপিং কোঅর্ডিনেটকে সংজ্ঞায়িত করে, যা আপনাকে সম্পূর্ণ DOM নোডের পরিবর্তে আপনার টেক্সচারে এলিমেন্টের শুধুমাত্র একটি অংশ কপি করতে দেয়:

প্রপার্টি ধরন বিবরণ
source প্রয়োজন Element বা ElementImage টেক্সচারে আঁকার জন্য টার্গেট DOM এলিমেন্ট (বা আগে থেকে ক্যাপচার করা ElementImage ইনস্ট্যান্স)।
sourceX ঐচ্ছিক (চারটিই অথবা কোনওটিই নয়) ফ্লোট অনুভূমিক X-কোঅর্ডিনেট অফসেট (CSS পিক্সেলে) যা সোর্স সাব-রেকট্যাঙ্গেল স্লাইসের উপরের বাঁদিকের কোণকে সংজ্ঞায়িত করে।
sourceY ঐচ্ছিক (চারটিই অথবা কোনওটিই নয়) ফ্লোট উল্লম্ব Y-অক্ষ অফসেট (CSS পিক্সেলে) যা সোর্স সাব-রেকট্যাঙ্গেল স্লাইসের উপরের বাঁদিকের কোণকে সংজ্ঞায়িত করে।
sourceWidth ঐচ্ছিক (চারটিই অথবা কোনওটিই নয়) ফ্লোট ক্রপ ও রাস্টারাইজ করার জন্য সোর্স সাব-রেকট্যাঙ্গেলের প্রস্থ (CSS পিক্সেলে)।
sourceHeight ঐচ্ছিক (চারটিই অথবা কোনওটিই নয়) ফ্লোট ক্রপ ও রাস্টারাইজ করার জন্য সোর্স সাব-রেকট্যাঙ্গেলের উচ্চতা (CSS পিক্সেলে)।

destination টার্গেট GPU টেক্সচারকে সংজ্ঞায়িত করে যা রেন্ডার করা DOM স্ন্যাপশট গ্রহণ করে, সাথে ঐচ্ছিক ডেস্টিনেশন অফসেট, মিপ লেভেল এবং টেক্সচারের একটি নির্দিষ্ট অঞ্চলে পিক্সেল রাখার জন্য কপি ডাইমেনশন:

প্রপার্টি ধরন বিবরণ
texture প্রয়োজন GPUTexture প্রি-অ্যালোকেট করা ডেস্টিনেশন WebGPU টেক্সচার যা রেন্ডার করা DOM পিক্সেল স্ন্যাপশট পাবে।
sizeটি ঐচ্ছিক GPUExtent3D ডেস্টিনেশন টেক্সচারের মধ্যে এলিমেন্ট স্কেল ও রাস্টারাইজ করার জন্য প্রস্থ ও উচ্চতা (ফিজিক্যাল টেক্সচার পিক্সেলে, যেমন, { width, height })।
originটি ঐচ্ছিক GPUOrigin3D টেক্সচারের মধ্যে 3D ডেস্টিনেশন অফসেট (x, y, z) যেখানে রাস্টারাইজড পিক্সেল লেখা হবে। ডিফল্ট হিসেবে [0, 0, 0] সেট করা থাকে।
mipLevelটি ঐচ্ছিক GPUIntegerCoordinate ডেস্টিনেশন টেক্সচারের নির্দিষ্ট মিপম্যাপ লেভেল যাতে লিখতে হবে। ডিফল্ট হিসেবে 0 সেট করা থাকে।
aspectটি ঐচ্ছিক GPUTextureAspect কোন টেক্সচার অ্যাসপেক্টে কপি করতে হবে তা নির্দিষ্ট করে ("all", "stencil-only", বা "depth-only")। ডিফল্ট হিসেবে "all"-এ সেট করা থাকে।
colorSpaceটি ঐচ্ছিক PredefinedColorSpace আপলোড করার সময় রঙ কনভার্ট করার জন্য ডেস্টিনেশন কালার স্পেস (যেমন, "srgb", "display-p3")। ডিফল্ট হিসেবে "srgb" সেট করা থাকে।
premultipliedAlphaটি ঐচ্ছিক বুলিয়ান আপলোড করার সময় আলফা কালার চ্যানেলে প্রি-মাল্টিপ্লাই করা হবে কিনা। ডিফল্ট হিসেবে false সেট করা থাকে।

drawElementImageToTexture() পদ্ধতি কল করে paint ইভেন্টের মধ্যে আপনার টেক্সচারে এলিমেন্ট আপলোড করুন:

canvas.addEventListener("paint", (event) => {
  const sourceDict = {
    source: myElement,
    // Optional sub-rectangle crop in CSS pixels
    // (defaults to full element if omitted):
    sourceX: 0,
    sourceY: 0,
    sourceWidth: myElement.offsetWidth,
    sourceHeight: myElement.offsetHeight,
  };

  const destDict = {
    texture: myTexture,
    size: { width: myElementWidth, height: myElementHeight },
  };

  // Upload the latest DOM snapshot into the pre-allocated GPUTexture
  device.queue.drawElementImageToTexture(sourceDict, destDict);
});

জ্যামিতি সিঙ্ক্রোনাইজ করুন

রেন্ডার করা ক্যানভাস আউটপুটের সাথে DOM হিট-টেস্টিং এবং অ্যাক্সেসিবিলিটি ফোকাস রিং অ্যালাইন করতে, একটি DOMMatrix ট্রান্সফর্ম তৈরি করুন এবং updateElementGeometry() পদ্ধতির মাধ্যমে এটি প্রয়োগ করুন:

// Construct a transform as needed in CSS pixels
// relative to the canvas, for example:
// 1/8 of the canvas width from the left edge, vertically centered.
// scaleX, scaleY: canvas grid pixels per CSS pixel (from resize observer)
const canvasCssWidth = canvas.width / scaleX;
const canvasCssHeight = canvas.height / scaleY;
const elementCssHeight = canvas.getElementImageDefaultSize(myElement).height / scaleY;
const x = canvasCssWidth / 8;
const y = (canvasCssHeight - elementCssHeight) / 2;
const transform = new DOMMatrix().translate(x, y);

// Synchronize the element's DOM hit-testing and accessibility geometry
canvas.updateElementGeometry(myElement, { canvasTransform: transform });

পরবর্তী ধাপ