关于gpu:WebGPU-规范篇-11-Canvas上下文

6次阅读

共计 2886 个字符,预计需要花费 8 分钟才能阅读完成。

系列博客总目录:https://segmentfault.com/a/1190000040716735


对应标准中 Canvas Rendering 一章

1 GPUCanvasContext

GPUCanvasContext 类型,其对象被称作 WebGPU 上下文。

它的作用就是让 HTML 上的 Canvas 元素,作为 WebGPU 中的一个纹理,与 WebGPU 进行渲染互动。

它的获取办法同 WebGLRenderingContext

const canvas = document.createElement('canvas')
const context = canvas.getContext('webgpu')

然而它与 WebGLRenderingContext 最大的不同是,它只负责与 Canvas 的沟通,在 WebGPU 端简略地扮演着 Canvas 与 WebGPU 的沟通桥梁,让 Canvas 作为一个纹理对象;而后者除了上述职责外,还包含创立 WebGL 子对象,绑定、编译着色器、触发渲染等等等等。

它的定义如下:

[Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUCanvasContext {readonly attribute (HTMLCanvasElement or OffscreenCanvas) canvas;

  undefined configure(GPUCanvasConfiguration configuration);
  undefined unconfigure();

  GPUTextureFormat getPreferredFormat(GPUAdapter adapter);
  GPUTexture getCurrentTexture();};
  • canvas 属性,你能够再获取 Canvas 元素;
  • configure 办法,用于配置 Canvas 的上下文,通知 WebGPU 这个 Canvas 能表演一个什么样的纹理对象;它接管一个对象参数,它的类型是 GPUCanvasConfiguration;
  • unconfigure 办法是 configure 办法的副作用,即勾销配置,并移除配置时产生的纹理对象;
  • getPrefferedFormat 办法接管一个适配器对象,返回一个适合适配器对象的纹理格局;
  • getCurrentTexture 办法返回 Canvas 所表演的那个 GPUTexture 对象, 须要留神的是 ,每一帧都要应用这个办法获取对应的 GPUTexture(如果是渲染管线用到了色彩附件来输入的话)。

2 GPUCanvasConfiguration 类型

配置 Canvas 时的对象参数的类型。

enum GPUCanvasCompositingAlphaMode {
  "opaque",
  "premultiplied",
};

dictionary GPUCanvasConfiguration {
  required GPUDevice device;
  required GPUTextureFormat format;
  GPUTextureUsageFlags usage = 0x10;  // 等价 GPUTextureUsage.RENDER_ATTACHMENT
  GPUPredefinedColorSpace colorSpace = "srgb";
  GPUCanvasCompositingAlphaMode compositingAlphaMode = "opaque";
  GPUExtent3D size;
};
  • device,即设施对象;
  • usage,纹理用处,Canvas 所表演的纹理默认是用来做色彩附件,即默认值 0x10
  • colorSpace,Canvas 的色调空间,只能是 “srgb”;
  • formatGPUTextureFormat 类型,即 Canvas 所表演的纹理对象的格局;
  • compositingAlphaMode,GPUCanvasCompositingAlphaMode 枚举类型,示意合成到 Canvas 上时的透明度选项,默认 “opaque”(不通明);
  • size,示意 Canvas 所表演的纹理尺寸有多大,默认会用 Canvas 的画布宽高(而不是 CSS 宽高)。

举例

context.configure({
  device: someDevice,
  format: context.getPreferredFormat(someDevice.adapter),
  size: [
    context.canvas.clientWidth * devicePixelRatio,
    context.canvas.clientHeight * devicePixelRatio,
  ]
})

GPUCanvasCompositingAlphaMode 枚举类型

“opaque” 示意 Canvas 表演的纹理的合成选项是不通明;”premultiplied” 示意 Canvsa 表演的纹理对象合成到 Canvas 时要与透明度事后相乘运算。

3 Canvas 尺寸变更问题

GPUCanvasContext 对象的 size 属性除非再次应用 configure 办法设置,否则是不变的。

如果在调用 configure 办法时没有明确指定其 size,那么它就会用 Canvas 对应的宽高。

如果在维度方面不匹配纹理对象,那么将会主动缩放以达到匹配。

webgl2d 上下文对象不一样,WebGPU 上下文对象对应的 canvas 元素的画布宽高(而不是 CSS 的宽高)仅受上面两个因素影响:

  • 画布默认的宽高(如果没被 CSS 暗藏)
  • WebGPU 上下文对象调用 configure 办法时

译者注

WebGPU 的绘图区域大小,它除了应用上下文对象的 configure 办法重设之外,没别的办法能够批改。在调用 configure 办法重设时,如果不指定 size 参数,那么它会主动读取 Canvas 元素的画布宽高(非 CSS 宽高)。

你能够应用上面的代码实现自动绘图分辨率匹配:

const canvas = document.createElement('canvas');
const context =  canvas.getContext('webgpu');

const resizeObserver = new ResizeObserver(entries => {for (const entry of entries) {if (entry != canvas) {continue;}
    context.configure({
      device: someDevice,
      format: context.getPreferredFormat(someDevice.adapter),
      size: {width: entry.devicePixelContentBoxSize[0].inlineSize,
        height: entry.devicePixelContentBoxSize[0].blockSize,
      }
    });
  }
});
resizeObserver.observe(canvas);

在 WebGL 中,通常每一帧都会执行 resize 函数以确保 CSS 分辨率和 canvas 分辨率统一,而后重设 viewport。

正文完
 0