HTML در بوم WebGPU

ارائه HTML در بوم WebGPU همه مزایای HTML در بوم WebGL را ارائه می‌دهد، مانند اعمال جلوه‌های سایه‌زن به DOM یا ادغام HTML تعاملی در صحنه‌های سه‌بعدی. بااین‌حال، WebGPU مزایای قابل‌توجهی نسبت‌به WebGL ارائه می‌دهد.

این راهنما نشان می‌دهد که چگونه HTML را در بوم WebGPU رندر کنید. درباره HTML-in-Canvas در نمای کلی API بیشتر بدانید.

برای رندر کردن HTML در بوم WebGPU، مراحل زیر لازم است:

  1. بوم نقاشی‌تان را آماده کنید. شاخصه‌های مناسب را به‌صورت اعلانی تنظیم کنید تا مرورگر بداند که باید HTML را در بوم رندر کند. این راه‌اندازی در بافت‌های 2D،‏ WebGL، و WebGPU یکسان است. با نحوه راه‌اندازی بوم و نحوه اعلام عناصر HTML برای ترسیم مستقل آشنا شوید.
  2. HTML را به‌عنوان بافت اعمال کنید:
    1. فضای ذخیره‌سازی بافت GPU را ازقبل اختصاص دهید.
    2. عکس آنی DOM را به‌عنوان بافت بارگذاری کنید.
  3. مدل شیءگرای سند و پیکسل‌ها را همگام‌سازی کنید.

رسم عنصر HTML به‌عنوان بافت WebGPU

در WebGPU، عناصر HTML بااستفاده از drawElementImageToTexture() به‌عنوان بافت‌های دوبعدی در GPU بارگذاری می‌شوند.

پیش‌اختصاص دادن فضای ذخیره‌سازی بافت

WebGPU به تخصیص حافظه صریح نیاز دارد. قبل‌از کپی کردن پیکسل‌های DOM در بافت، باید بااستفاده از روش device.createTexture()، حافظه 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 رندرشده را دریافت می‌کند، به‌همراه افست‌های مقصد اختیاری، سطوح mip، و ابعاد کپی برای قرار دادن پیکسل‌ها در ناحیه خاصی از بافت تعریف می‌کند:

دارایی نوع شرح
texture الزامی است GPUTexture بافت WebGPU مقصد ازپیش اختصاص‌داده‌شده که عکس آنی پیکسل DOM رندرشده را دریافت خواهد کرد.
‫size پرسش اختیاری GPUExtent3D عرض و ارتفاع (به پیکسل‌های بافت فیزیکی، برای مثال، { width, height }) برای مقیاس‌بندی و شطرنجی کردن عنصر در بافت مقصد.
‫origin پرسش اختیاری GPUOrigin3D انحراف مقصد سه‌بعدی (x, y, z) در بافت که پیکسل‌های شطرنجی‌شده در آن نوشته خواهد شد. پیش‌فرض‌ها به [0, 0, 0].
‫mipLevel پرسش اختیاری GPUIntegerCoordinate سطح mipmap خاص بافت مقصد برای نوشتن در آن. پیش‌فرض‌ها به 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 });

مراحل بعدی