Hello, WebGPU——多重采样抗锯齿

「这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战」。

前言

接上文 Hello WebGPU——绘制第一个三角形,我们利用WebGPU绘制出了我们的第一个三角形,但是我们发现它有一些小小的问题。比如下面这样:

我们放大三角形的边缘,我们可以清晰地看到三角形的边缘出现了很多锯齿。 image.png

那么,为了提高渲染质量,我们不得不进行抗锯齿的处理。进行抗锯齿的方法有很多,比如

  • MSAA(Multi Sample Anti Alias) 多重采样抗锯齿
  • SSAA (Super Sample Anti Alias) 超采样抗锯齿

其中关于MSAA与SSAA的区别可以参考这篇文章:FXAA、FSAA与MSAA有什么区别?

在WebGPU中,WebGPU内置了多重采样抗锯齿,今天就来介绍一下如何在WebGPU中开启多重采样抗锯齿。

WebGL中开启多重采样抗锯齿

在WebGL中开启抗锯齿的方法很简单,我们只需要在获取WebGL上下文的时候,通过一个配置即可开始抗锯齿。

const gl = canvas.getContext('webgl', {
    antialias: true,
})
复制代码

WebGPU中开启多重采样抗锯齿

那么我们想要在WebGPU中开启多重采样抗锯齿应该怎么做呢?

在前文的基础上:

步骤一: 在PSO中增加 multisample 配置项


  const pipeline = device.createRenderPipeline({
    vertex: {
      module: device.createShaderModule({
        code: triangleVertWGSL,
      }),
      entryPoint: 'main',
    },
    fragment: {
      module: device.createShaderModule({
        code: redFragWGSL,
      }),
      entryPoint: 'main',
      targets: [
        {
          format: presentationFormat,
        },
      ],
    },
    primitive: {
      topology: 'triangle-list',
    },
    multisample: {
      count: 4
    }
  });
复制代码

在创建PipelineStateObject的时候,我们这里增加了 multisample 的配置项

步骤二:创建一个纹理对象

 const texture = device.createTexture({
    size: presentationSize,
    sampleCount: 4,
    format: presentationFormat,
    usage: GPUTextureUsage.RENDER_ATTACHMENT,
  });
复制代码

创建一个纹理对象,我们会将其附着到相应的 renderPass的颜色缓冲区上,换句话说就是把渲染的结果渲染到我们创建的这张纹理上,而不是直接渲染到canvas画布上!

步骤三:给RenderPass设置 viewresolvedTarget

最后,我们只需要将我们刚刚创建好的纹理对象设置到renderPass中

renderPassDescriptor: GPURenderPassDescriptor = {
      colorAttachments: [
        {
          view: texture.createView(),
          resolveTarget: context.getCurrentTexture().createView(),
          loadValue: { r: 0.0, g: 0.0, b: 0.0, a: 1.0 },
          storeOp: 'store',
        },
      ],
    };
    
passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
复制代码

这里着重解释一下 viewresolvedTarget 的含义:

view

这里的view是 WebGPUTexture 通过 createView() 方法所创建的,它是纹理的一类子资源,它可以作为颜色附件(color attachment)的输出。作者猜测这里应该是类似于在类型化数组中,Float32ArrayArrayBuffer 之间的关系。

resolvedTarget

如果 renderPass 中的 color attachment被指定了是 multisampled,那么该纹理视图它被用于接受多重采样后的结果。

OK,开启抗锯齿三部曲我们已经完成了,我们来一起看一下效果如何吧?

image.png

可以看到,三角形的锯齿边缘多了一些半透明的像素,最终还是可以得到一个不错的效果的。

总结

好了,今天的内容相对比较简单,我们主要学习了如何在WebGPU中开启MSAA抗锯齿。这可是一个提升渲染质量的必备利器!开启的方式相比WebGL稍微复杂了一些,但是也不算是特别的复杂,总的来说还是能够接受的。主要分为3步:

  1. 在PSO对象中增加 multisample的配置,告诉渲染管线,这一次我需要进行多重抗锯齿
  2. 创建一个纹理,用这个纹理接受渲染管线的输出
  3. 修改 renderPass 中的 viewresolvedTarget,将我们多重抗锯齿的结果绘制到canvas画布上。

OK,今天的内容就这么多,如果你觉得文章对您有用,别忘了点个赞~

Guess you like

Origin juejin.im/post/7055495358616436750