You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

启用抗锯齿时WebGPU模板缓冲区2D裁剪结果消失的原因及解决

问题原因

启用小三角形抗锯齿后裁剪结果消失,核心原因是WebGPU的多采样纹理解析(resolve)操作会覆盖整个目标纹理:

  • 第三个RenderPass中创建的sampleTexture是全新的多采样纹理,初始内容为未定义状态,并非继承画布已有的裁剪结果。
  • 当设置resolveTarget为画布纹理时,WebGPU会将整个多采样纹理的内容解析后直接替换画布内容,而非仅更新绘制了小三角形的区域。
  • 多采样纹理中除小三角形外的区域都是未初始化的垃圾数据,解析后直接覆盖了之前通过模板裁剪绘制的内容,导致裁剪结果消失。

解决方法

要在已有画布内容上叠加抗锯齿元素,需先将画布现有内容复制到多采样纹理中,再绘制新元素,最后解析回画布。修改后的核心代码如下:

{
  const antialias = true
  const sampleCount = 4
  const sampleTexture = device.createTexture({
    size: [canvas.width, canvas.height],
    sampleCount,
    format: presentationFormat,
    usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_DST, // 添加COPY_DST权限
  })
  
  // 关键步骤:将画布现有内容复制到多采样纹理
  device.queue.copyExternalImageToTexture(
    { source: canvas },
    { texture: sampleTexture },
    [canvas.width, canvas.height]
  )

  const verts = new Float32Array([0.9, 0.9, 0.9, 0.7, 0.7, 0.9]);
  const vertexBuffer = device.createBuffer({
    size: verts.byteLength,
    usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
  });
  device.queue.writeBuffer(vertexBuffer, 0, verts);
  const pipeline = device.createRenderPipeline({
    layout: 'auto',
    vertex: {
      module,
      entryPoint: 'vs',
      buffers: [{ arrayStride: 8, attributes: [ {shaderLocation: 0, offset: 0, format: 'float32x2'}] }],
    },
    fragment: {
      module,
      entryPoint: 'fs',
      targets: [{format: presentationFormat}],
    },
    multisample: antialias ? { count: sampleCount } : undefined,
  });
  const pass = encoder.beginRenderPass({
    colorAttachments: [{
      view: sampleTexture.createView(),
      resolveTarget: context.getCurrentTexture().createView(),
      loadOp: 'load', // 加载已复制的画布内容
      storeOp: 'discard', // 多采样纹理无需保留
    }],
  });
  pass.setPipeline(pipeline);
  pass.setVertexBuffer(0, vertexBuffer);
  pass.draw(3);
  pass.end();
}

修改说明:

  1. 给sampleTexture添加GPUTextureUsage.COPY_DST权限,允许向其复制内容。
  2. 通过copyExternalImageToTexture将画布现有裁剪结果复制到多采样纹理,确保初始内容与画布一致。
  3. RenderPass的loadOp设为'load',加载多采样纹理中的已有内容后再绘制小三角形,最后解析回画布时不会覆盖原有裁剪结果。

内容的提问来源于stack exchange,提问作者plantain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 00:54:59