赞
踩
推荐:使用 NSDT场景编辑器 助你快速搭建3D应用场景
粗略地概述一下WebGPU与WebGL的不同之处是很有用的。在不涉及太多复杂的技术细节的情况下,两者的整体设计大致如下:
一个很好的例子也显示在这篇关于 Safari 中的 WebGPU 的博客文章.下面是一些用于渲染单个对象的 WebGL 代码:
- gl.useProgram(program1);
- gl.frontFace(gl.CW);
- gl.cullFace(gl.FRONT);
- gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_MIN);
- gl.blendFuncSeparate(gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA, gl.ZERO);
- gl.colorMask(true, false, true, true);
- gl.depthMask(true);
- gl.stencilMask(1);
- gl.depthFunc(gl.GREATER);
- gl.drawArrays(gl.TRIANGLES, 0, count);
这是WebGPU中的等效项:
- encoder.setPipeline(renderPipeline);
- encoder.draw(count, 1, 0, 0);
请注意,所有等效状态都将提前为 renderPipeline 设置。但是你不需要理解代码就能看到重点:要运行的代码更少,所以速度更快。
Mozilla Hacks 博客文章在 Firefox 中体验 WebGPU还包括对WebGL和WebGPU之间差异的更多技术摘要。
WebGPU 有很多好处(其中许多与其他新的低级图形 API 共享):
简而言之,这对所有相关人员都有好处 - 对于像我们这样的应用程序开发人员更好,对像nVidia和AMD这样工作更容易的硬件制造商更好,对获得更快性能的游戏玩家更好。
但是,没有什么是完美的,并且有一个很大的缺点:必须完全重写所有渲染代码才能利用这一点。这不仅适用于必须重写才能使用 WebGPU 的 Construct's 渲染器 - 它还适用于整个图形堆栈,包括浏览器的渲染代码、图形驱动程序代码,可能还有操作系统的一部分。这也是在所有艰难的规范工作完成之后,计算出 API 应该如何设计为跨一系列不同的低级图形 API 工作的所有细节。这是整个行业的大量工作,因此自然需要时间才能实现所有这些工作,并且这些新技术最终需要时间才能广泛应用。
尽管 WebGPU 仍在开发中,并且可能距离发布还有很长的路要走,但 WebGPU 的实验版本在某些浏览器中可用。我一直在Chrome Canary上尝试它,它允许我为Construct制作早期的WebGPU渲染器的原型。
与低级 API 的情况一样,在到达任何地方之前可能需要大量代码。我花了大约 1000 行 WebGPU 代码,才终于在 Construct 中看到了第一个使用 WebGPU 渲染的精灵!
混合是错误的,当我仔细观察时,渲染质量也不是很好,但你绝对可以看到图像!经过一些进一步的工作,进展更快,修复了混合,提高了渲染质量,并添加了更多功能。不久之后,我就让幽灵射手示例完全在 WebGPU 中渲染!
不过,这个游戏的渲染要求非常简单:它只不过是基本的精灵和“加法”混合模式。代码仍然非常笨拙,没有做好生产准备,并且有各种各样的更复杂的渲染功能需要涵盖 - 我预计效果合成器特别棘手。(有关背景,请参阅我过去的博客文章构造的效果合成器第 1 部分和第 2 部分.)WebGPU 本身离完成还有很长的路要走 - 例如,规范团队刚刚就着色器语言的发展方向达成一致。一旦新的着色器语言被指定、开发和测试,我们就可以将 80+ 个 Construct 现有的着色器效果移植到它身上。因此,虽然这是有希望的早期进展,但仍有很长的路要走。
在Construct中使用WebGPU进行了一些初步原型设计后,它看起来非常有前途,并且是Web游戏的一项令人兴奋的发展。其中大部分是基于实验性 WebGPU 支持的早期工作,因此可能会发生变化,但以下是我的一些早期发现。
WebGPU over WebGL 的一个关键设计方面对 Construct很重要,那就是命令可以重新排序。为了解释为什么这很重要,我需要简要解释一下WebGL渲染器在内部是如何工作的。当渲染大量精灵时,它会将它们批处理在一起,正如我过去的博客文章所解释的那样。但是,在执行此操作时,它还会构建要渲染的所有精灵的大量坐标列表(顶点缓冲区)。为了提高性能,必须一次性将此列表发送到 GPU。但是在绘制完所有精灵之前,列表还不完整!因此,WebGL 渲染器会对所有 WebGL 命令进行排队,将它们延迟到列表完成。该过程如下所示:
在许多情况下,这意味着在渲染期间建立一大堆命令,然后在帧结束时,再次遍历命令队列以实际运行它们。
WebGPU 的设计优势在于,步骤 2 - 将坐标列表发送到 GPU - 可以重新排序。这完全消除了对队列的需求!因此,该过程现在可能如下所示:
就是这样!现在,所有 WebGPU 命令都在坐标列表发送到 GPU 后运行,我们完全消除了构建自己的命令队列的需要。
这是 Construct渲染器的一个很大的架构改进。它既简单多了,更易于使用,也更高效。
如上所述,WebGPU 使用的实际函数调用更加清晰和组织。因此,虽然更加低级,但一旦我进入了事物的摇摆,我实际上发现使用 WebGPU 更容易、更明显。特别是WebGL的两步绑定模型,你必须首先“绑定”你想要改变的东西,然后改变它,是笨拙和容易出错的。WebGPU 几乎完全取消了这一点,这本身就是一个很大的改进——整个 API 也有类似的改进。此外,更接近硬件的工作方式意味着我可以调整调用以达到 Construct渲染目的的最有效,而不是依赖于图形驱动程序中发生的各种复杂处理,这可能不快,有时甚至可能不正确。
我认为现在发布实际的基准测试数字还为时过早 - WebGPU 和我的原型代码还有很多东西需要改变。然而,我的早期性能测试已经显示出有希望的结果,主要是在以前对WebGL具有挑战性的情况下。我设计了一些渲染“酷刑测试”,故意生成很长的绘制命令列表。这些在WebGPU中尤其快得多。我怀疑这既是因为删除了我之前解释的批处理队列,还因为图形驱动程序要简单得多,因此开销也更少。这很可能转化为有意义的实际性能改进,特别是对于无法有效批处理的游戏。
我希望避免的结果是必须为两个渲染器编写两次所有渲染代码。这是我们几年来同时拥有canvas2d和WebGL渲染器时必须管理的东西。这意味着需要大量额外的工作来检查它们的渲染方式是否相同,修复两者中的错误,并且每次我们更改某些内容时,都必须在两个地方进行更改并验证两者。这也意味着第三方插件开发人员也必须为两者编写代码。
它很早,但看起来 WebGPU 实际上足够接近我们现有的渲染代码,应该可以在我们自己的绘图代码和第三方插件中使用相同的渲染代码来支持它。简而言之,我们有自己的渲染器类,所有 Constructer 代码都使用,而不是直接处理 WebGL。渲染器类在内部处理 WebGL 的所有细节。看起来这个类应该能够仅将 WebGPU 作为内部更改来处理,从而避免了在 Construct 中更改所有其他代码的需要。这一点很重要,可以使其易于维护并避免必须要求第三方开发人员进行更改(如果他们停止维护他们的插件,这将永远不会发生)。
一个重大的变化是WebGPU将使用与WebGL不同的着色器语言。这意味着所有效果很可能都必须重写,第三方也必须这样做。不过,这是一个较小的影响,应该是可控的。
一个常见的问题是“我们将通过 WebGPU 获得哪些新功能?
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。