可能取代Vulkan和OpenGL的WebGPU为何如此重要?
WebGPU 作为新一代的 WebGL,为开发者提供了在浏览器绘制 3D 的新方法,它很可能也会取代 Canvas,成为在 Web 浏览器中绘制 2D 的新方式,甚至可能取代 Vulkan 和 OpenGL,成为任何软件或编程语言绘制图形的标准方式。原文链接:https://cohost.org/mcc/post/1406157-i-want-to-talk-about-webgpu未经授权,禁止
WebGPU 作为新一代的 WebGL,为开发者提供了在浏览器绘制 3D 的新方法,它很可能也会取代 Canvas,成为在 Web 浏览器中绘制 2D 的新方式,甚至可能取代 Vulkan 和 OpenGL,成为任何软件或编程语言绘制图形的标准方式。
原文链接:https://cohost.org/mcc/post/1406157-i-want-to-talk-about-webgpu
未经授权,禁止转载!
作者 | andi 译者 | 卞安
责编 | 梦依丹
出品 | CSDN(ID:CSDNnews)
WebGPU是WebAssembly的一种新API,它提供了一种在Web浏览器中使用GPU的方式。它为现代 GPU 提供更好的兼容、支持更通用的 GPU 计算、更快的操作以及能够访问到更高级的 GPU 特性。
经过6年研发,WebGPU被正式集成到Chrome 113中。自此,开发者终于可以在Web浏览器端实现3A级渲染的3D应用了。
图1-1 黑色背景上的三角形
单击右侧地址,https://data.runhello.com/j/wgpu/1/(复制到浏览器中打开) 如果你能够看到一个彩色的三角形如图1所示,那么说明你的浏览器已经支持WebGPU。WebGPU有望在今年年底出现在每种电脑的浏览器中,移动端可能会稍晚些。
如果你并非程序员,那么,WebGPU对你可能没有太大的影响或者体验,和以前使用Flash差不多。但对于程序员来说,WebGPU可能对你意义非凡,不妨跟随作者的脚步,来了解WebGPU的前世今生,以及它为何会如此重要。
注:为了更贴近原文,本文以第一人称的口吻来编译。
WebGPU诞生的背后
人们过去在电脑上制作3D有两种方式:要么自已编写数学库来渲染3D效果,要么买一台“SGI”电脑,SGI是一个人名,他设计了一个可以提供3D渲染的图形库,可以通过C语言编写的API来调用渲染3D模型。不知什么时候,有人开始为普通电脑制作插卡式的3D加速卡,这种插卡可以实现与SGI的大型UNIX机器相同的加速处理,于是有一天,SGI发布了一个公共版本的图形库,这样不管是UNIX电脑还是普通电脑的加速卡都可以运行,这就是OpenGL,原本IRISGL中的 “color()”和”rectf()”变成了OpenGL中的 ”glColor()”和 “glRectf()”。
不过事情开始变得混乱,掌握着PC操作系统的微软公司并不打算使用OpenGL,而是决定开发自己的Direct3D,而其它一些3D卡供应商也有自己的API标准,所以有一段时间,某些游戏只能在特定显卡上加速,游戏研发公司有时不得不为游戏产品编写多个版本的3D模块,一次用软件渲染器,其它次是为他们想要支持的每种加速卡编写调用。我当时觉得Direct3D最终将设法把所有这些整合到一个标准中,因为当时如果不使用Windows操作系统,处理这些事儿将很麻烦。DirectX试图通过将游戏公司锁定在微软操作系统中,而且将DirectX设置为它们唯一可用的底层库,有一段时间它确实做到了。
有一段时间,你可以经常听到大家说Direct3D比OpenGL好,不过很快OpenGL就追上了落后的关键功能,比如实现了着色器。主要原因在于组成OpenGL架构审查委员会的各个加速卡厂商成员在定义细节上浪费了较长的时间争论不休使得进展缓慢,可惜的是微软在当时只实现了一些基本的接口和框架,而期望具体实现的工作丢给加速卡厂商。
最早期的OpenGL是一个“固定函数渲染器”,3D渲染时固定的按顺序执行相应的功能函数。
上图中的每个方框都对应一些具体的函数,你可以通过调用它们完成相应的操作,但只限于3D加速卡所提供的操作。如果你的游戏中有阴影或雾,那是因为 OpenGL或扩展库中提供了用于绘制阴影或雾的功能。如果想要一些ARB(OpenGL架构评审委员会)没有提供的功能,或者想要以独特的方式制作阴影或雾以使得游戏看起来与其他游戏不同,该怎么办呢?
不久之后,移动设备开始流行,于是在移动设备上进行3D渲染变得越来越重要。DirectX没办法运行在这些设备的系统上,但是2005年左右的移动芯片要想运行OpenGL也是很难的。因为OpenGL有点太大了,毕竟它拥有SGI时代遗留下来的所有这些功能,于是一种新的东西“OpenGL 2.0”出现了,专门用于处理着色器和相关的支持,这导致了两个不相关的API被整合在同一个图形库中,许多OpenGL 1.x的函数都不能使用。
该规范说视频卡必须支持每个OpenGL的函数,但并没说必须硬件支持,因此在90年代早期设计的一些老旧功能,驱动程序会将整个屏幕复制到内存中在CPU上执行,然后再将结果图像复制到显卡,这时FPS一下子从60帧降到几乎一动不动。这些历史的遗留问题都为移动GPU的制造商带来大量额外的工作,为了解决这个问题,更名为Khronos的ARB(OpenGL架构评审委员会)引入了一套精简的OpenGL“ES”规范,它删除了必要功能之外的所有内容。开发者不必再为每个多边形或每个顶点调用函数,而是使用新的API来指定内存中的数据数组位置,同时支持固定管线或着色器管线。
这样一下子使得程序员的事情变得简单了许多,于是开发者纷纷用OpenGL ES重写项目。与着色器引发的情况一样,OpenGL ES的出现也带来了一个奇怪的影响:从这时开始,Khronos的决策越来越由硬件制造商的需求驱动,而不是程序员。
随着支持OpenGL ES的设备出现,OpenGL开始了飞跃。智能手机iPhone的流行为学习和使用OpenGL提供了坚实的市场理由,任天堂游戏机也开始使用OpenGL。OpenGL在功能上开始赶上了DirectX,特别是浏览器开发商也从之前的傲慢中,开始支持OpenGL ES的JavaScript版本“WebGL”,为此他们还在JavaScript语言中添加了对二进制数组的访问,这可是以前没有的事儿。这时候的OpenGL发展的似乎顺风顺水,风头无二,但实际上是这样么?
不!其实情况很糟糕。随着OpenGL的不断成熟,OpenGL分裂出多个略有不同的标准,并且各自具有不同的交叉兼容性。每次解决OpenGL之前版本的错误最终都会将API复制为一个名称略有不同且签名略有不同的新功能。OpenGL的另一个大问题是它有很多共享的全局状态,本应该用于解决这个问题的VAO和VBO最终却变成了必须跟踪的全局状态。而随着通用GPU的发展,程序员开始意识到GPU和CPU一样好,编程却稍微简单一些,所以他们开始使用一些编程技巧来加速一些非图形应用程序,比如将数据塞进像素着色器中,并读回包含编码结果的纹理。最初Khronos也迎合了这一点,OpenGL的结构被设计的很乱,其中一些只能在某些机器上运行。更糟糕的是一些显卡商驱动支持的很差,Windows的OpenGL驱动程序中更是臭名昭著。一个叫做“AZDO”的人提出来一个解决方案,他发表在GDC演讲中,虽然我不相信GDC演讲是这个想法的起源,但这个演讲的确是Vulkan、DirectX 12和 Metal命名方案背后的原因,它使得驱动程序被架空了,想法是这样的:众所周知到2015年,显卡已经对特定的工作方式进行了标准化,并且这种方式预计在未来十年内不会改变。图形库最初是基于它们公开的功能进行设计,但驱动程序变得越来越复杂,不只是做你告诉他们的功能,也试图预判你要做什么操作并尝试以最优化的方式去执行,但很不巧经常猜错,这导致开发者常常处于尴尬的境地。AZDO通过图形库将函数调用与硬件实际执行的操作精确一致,这样驱动程序就无事可做。
现代图形API(比如 Vulkan、DirectX 12和Metal)基本上都抛弃了驱动程序,或者更确切地说,直接集成为驱动程序。函数直接映射到GPU的具体内部功能,无需让GPU进行猜测。这样就提供了强大的性能和控制力。现代图形库允许定义“管道对象”,图形着色器允许开发者替换图中的方框内容,而计算着色器允许使用一个大型着色器程序替换关系图,而管道对象允许定义自己的关系图。开发者可以决定哪些GPU内存块是源,哪些是目标,如何解释它们,以及如何处理它们,调用哪些着色器。这样所有历史遗留的混乱问题都得到了解决。状态绑定在整齐定义的对象中,而不再是全局的。显卡供应商之前总是以各自不同的方式设计他们的着色器编译器,因此将文本着色器语言替换为字节码格式,该格式易于实现且更易于编写编译器,Vulkan甚至允许为GPU内存编写自己的分配和释放处理。
这一切看起来很酷,但有一个问题,就是所有这些细粒度处理的复杂性太高,Vulkan基本上不可能手动编写。实际上,DX12和Metal提供了或多或少相同程度的细粒度复杂性,而且从各方面来看它们的编写都不错。但Vulkan并不是为手动编写而设计的。Khronos不希望你手写Vulkan,更确切地说,他们是不希望你直接手动编写。2015年GDC对外宣布Vulkan时,我正在台下和一些图形引擎和游戏开发人员在一块儿,听着他们的解释:“游戏开发人员实际上越来越不需要管游戏API ,而只需要是面向高级中间件进行开发,比如Unity 、Unreal 或其他的图形引擎,所以Vulkan是一个专为编写中间件而设计的图形库。”当Khronos家伙解释这一点时,我注意到旁边的中间件开发人员笑了,可以想像到,他们的生活即将变得轻松得多。 我的工作变得越来越复杂。Vulkan的使用很奇怪,每个Vulkan调用都涉及传入一两个巨大的结构体,这些结构体本身又会涉及其它更复杂的结构,每个结构和子结构都以一个小协议标头开头,解释它是什么以及它有多大。在分配内存之前,必须填写一个结构才能返回一个结构,该结构描述了应该在哪个结构中构建内存分配请求。这一切其实并没什么意义,除非你以前设计过一种编程语言,在这种情况下,你要不断的查看那些文档。这些文档却又编写的晦涩难懂,但它的确是完全按照硬件实现者想要的方式编写,并用来消除关于函数调用所做的所有歧义。简而言之,Vulkan不好用,这是硬件制造商和中间件开发商之间的拜占庭协议,至于开发者的感受...哈哈,反正我们的感受又不是协议的一部分。Khronos其实并没有忘记开发者,但他们只是做出了一个框架,这也好解释,他们无论如何都不可能设计完全符合开发者习惯的API,只能是尽可能将好用的API 编写到图形库里。Khronos 自信的认为,在 Vulkan发布的几年内就会有一堆高质量的开源封装库,开发者会直接使用这些封装库而不是Vulkan。但这些库后续并没有实现。事实证明,编写软件是一项复杂的工作,开源项目不会仅仅因为人们希望它们而实现。
这就引出了Vulkan在事后发展的问题。为了占领市场,微软开始持续更新高级图形API,而OpenGL只是草率的追赶。如果GPU供应商支持Vulkan成为通用标准,DirectX将只会变为微软某些体系性充的标准,但苹果却拒绝了。因为这时候苹果也推出了自己的产品“Metal”并宣布永远不会支持Vulkan,也不会再支持OpenGL。依我看这又是“DirectX”的历史重演罢了,在这个移动开发时代占主导地位的操作系统厂商,也在像微软在90 年代一样去推动专有图形API以促进开发人员锁定在自已的操作系统中。他们通过降低对硬件厂商的依赖,提供给开发人员真正想要使用的东西。
随着苹果的退出,情况一下子变得微妙起来。突然之间,Windows、Mac/iPhone、Linux/Android等操作系统都有自已的下一代图形API。Linux在Vulkan的驱动程序支持上有严重BUG,而且许多Linux设备在Vulkan已经推出七年后仍然不支持Vulkan,因此,Vulkan原生运行的唯一平台只有Android,不过局面没有想像的那么糟糕,Vulkan其实可以在Windows上正常运行,因为它是轻量级的东西,非常轻巧地放在硬件层的顶部,这意味着它们并没有那么难用,以至于出现了一个名为“MoltenVK”的基于Metal API实现Vulkan的仿真层,据说运行时几乎没有增加开销。但是如果你是一个开源的人,没有资源来应付不同的平台后端,那就比较麻烦了。从技术上讲,你的代码可以在所有平台上运行,而且具备在两个主要平台上调用本地图形API 的优势。简而言之,Vulkan解决了OpenGL的所有问题,代价是制造出没人想使用,也没有理由使用的东西。
WebGL是基于OpenGL ES设计的。但它却和OpenGL ES完全不同,从技术上讲,OpenGL ES从未真正在桌面上运行过,即便是桌面系统上的常规OpenGL也存在许多问题。因此,浏览器开发人员最终意识到,如果你想在Windows上发布OpenGL的兼容层,实际上在DirectX中编写OpenGL模拟器比直接使用OpenGL更容易,并且不需要协调不同显卡驱动程序对OpenGL的各种不兼容性。
开发人员还意识到,如果不同OpenGL驱动程序之间的兼容性差异是地狱级的麻烦事儿,那么四个不同浏览器之间的兼容性差异乘以三个操作系统再乘以不同的显卡驱动程序将是有史以来最糟糕的事情。在这种假设的绝望中,一个通过跨公司开源协作的成功解决方案出现了:“ANGLE”,这是一个BSD许可的OpenGL模拟器,最初由Google编写,但Firefox和Apple也都参与并实际做出了贡献,它用于对每个Web浏览器进行WebGL的支持。
但是大家并不想用WebGL,而是想要一个现代图形库,一个类似AZDO的东西。因此,一个W3C工作组开始制作Web Vulkan,他们将其命名为WebGPU。我不确定我对事件的看法是否正确,但我的看法是,苹果公司将会是工作组中要求最高的参与者,也是每个人最担心的一个参与者,所以据报道WebGPU完全满足了苹果公司的一切要求,这也使得 WebGPU 看起来真的很像 Metal。但据说Metal一直是三个现代图形 API 中最好使用的,所以这就是结果?受到ANGLE成功的鼓舞(此时它开始在非Web应用程序中用作独立库),并且有开发者希望将这个新API与WebASM一起使用,他们采取了将标准同时定义为JavaScript IDL和C头文件的步骤,以使得非浏览器应用程序也可以将其用作库。
WebGPU是ANGLE和Metal结合的产物,更是Vulkan所一直缺少的符合开发者习惯的“人体工程学层”。WebGPU在Web浏览器中运行,而微软和苹果都是浏览器标准委员会的成员,所以他们也是WebGPU的投资者,不仅WebGPU在他们的平台上可以像原生一样工作,而且用WebGPU开发的任何东西都可以在他们的操作系统上运行,WebGPU从第一天起就提供与 JavaScript/TypeScript、C++和Rust具有完全相同的兼容性。
我相信WebGPU才是我们一直在等待的东西。
WebGPU是什么样子的?
因为没有用过DirectX或Metal,我无法将WebGPU与这两种图形API进行对比,但与OpenGL和Vulkan相比,WebGPU使用起来非常令人耳目一新。记得我写Vulkan的时候,每次都被它的复杂性打败相比之下,WebGPU只有需要增加某些比较复杂的东西时才比较难受,因为有很多不同的对象需要跟踪,尤其是在初始化期间,但每个对象都与真实存在的东西所对应。不过你也可以将所有的复杂性塞进初始化时间,使实际绘制框架的过程非常简洁。
不过WebGPU有三个要注意的问题:
1、文本
2、线条
3、“讨厌鬼”
文本和线条基本上是相同的问题。WebGPU对他们支持的不够。WebGPU可以画线,但仅能绘制单像素宽度,而无法控制抗锯齿。因此,如果你想要一条“正常外观”的线条,你需要使用定制网格模型和着色器做一些复杂的事情。与文本类似,你也需要自己解析OTF字体文件并编写自己的着色器,或者找一个为你处理文本的库。
过去的图形API对线条或文本支持不够是很正常的,但WebGPU也如此就很令人恼火,毕竟Web浏览器已经有使用原始Canvas API的抗锯齿线条渲染器和最先进的文本渲染器,完全可以通过将文本转成Canvas API纹理,然后传输到WebGPU中渲染。
最后是WGSL,也就是我说的“讨厌鬼”。也许你可能不会这么在意,但是Vulkan的优势之一就是不需要使用特定的着色器语言。OpenGL使用GLSL,DirectX使用HLSL。Vulkan使用了一个字节码,称为SPIR-V,可以从任何想要的着色器语言中调用它。WebGPU最初使用SPIR-V,但后来苹果不同意。结果现在WebGPU使用WGSL,一种专为WebGPU开发的新语言作为其唯一的着色器语言。虽然WGSL比GLSL更好,特点是对于纯JavaScript的开发者来说,能够将着色器作为文本文件上传而不必编译为字节码也算是一种改进。但是如果能有选择就好了,起码WebGPU的“桌面”版本仍然保留SPIR-V作为选项。
如何使用WebGPU?
使用WebGPU有三种选择:
1、在浏览器中的JavaScript中使用它
2、在浏览器内的WebASM中的Rust/C++中使用它
3、在独立应用程序中的Rust/C++中使用它。
Rust/C++ API其实除了语言差异是很接近JavaScript 版本的,基于Rust和 C++ 开发的浏览器所调用的WebGPU API除了像SPIR-V这样的独立特定功能外基本是相同的。如果想要在独立应用程序中使用WebGPU,则需要调用Chrome或Firefox的组件,至于组件内部的实现则不需要考虑。
无论使用何种语言,w3.org的官方WebGPU规范文档都是该语言清晰明了的参考指南,你可以打开链接查看(https://www.w3.org/TR/WGSL/)。
除了编写着色器之外,WebGPU中的大多数“工作”都在构建“管道”对象,为每个“管道”中进行描述“我正在运行什么着色器,什么样的数据可以输入到它们中?”等信息,然后在队列中把这些管道链接起来:让计算管道生成顶点缓冲区,让渲染管道渲染到纹理中,执行最终渲染管道,使用渲染纹理渲染计算的顶点。
这里用图表形式展现了需要创建的所有内容,从最初设置WebGPU到渲染。看起来有点庞大,不过别担心,你只需从一些示例代码中复制并粘贴一大块代码罢了。
在初始化时的处理如下图:
每一帧的处理如下图:
以下是一些要注意的点:
- 在描述“网格”(要绘制的3D 模型)时,“顶点”缓冲区是空间中的点列表,“索引”是包含绘制点的顺序的可选缓冲区。
“队列对象”似乎没什么实际意义,因为只有一个全局队列。但未来预计WebGPU会加入线程,可能会有不止一个线程。
命令编码器一次只能处理一个管道,在进行下一个管道前,你必须将当前管道标记为已完成。不过可以使用多个命令编码器,一次将它们全部提交到队列。
如果想在OpenGL的着色器上设置自定义变量、属性或纹理时,可以按名称进行设置。但在WebGPU中,你必须在着色器中指定数字,并通过数字对它们进行寻址。
尽管纹理和缓冲区是两种不同的东西,但可以通过GPU将它们互相转换。
我没有在上面列出“pipeline layout”或“bind group layout”对象,因为我也不了解它们的作用。
在Rust API中,“Context”被称为“Surface”。我不知道是否有区别。
下面我们聊一些开发语言相关的注意事项:
TypeScript / NPM :
我所知道基于TypeScript 语言学习WebGPU的最好教程是Alain Galvin的“Raw WebGPU”教程(https://alain.xyz/blog/raw-webgpu)。它对以前没有使用过图形API的人来说更友好一些,并且它在末尾还有一个扩展资源列表。
由于代码片段不能直接运行,Alain的教程将一个完整的源repo与教程代码链接起来,我有一个基于Alain教程代码的示例repo(https://github.com/mcclure/ts-hello/tree/canvas-gpu),它添加了简单的动画,并使用了Preact. 并基于NPM和WebPack。
如果你以前不喜欢TypeScript:我建议你在WebGPU的学习中尝试一下使用TypeScript,除了WebGPU调用之外,你实际上不必向任何内容添加类型,而只需要键入“any”。但是构建该管道对象需要包含许多描述符,不过这些都是简单的JavaScript字典类型,这样如果拼错了一个键,或者忘记了关键字,或者意外地将GPU PrimitiveState表写成了GPU VertexState表。你可以让TypeScript告诉你错误,重新加载下,反复的查测崩溃。
如果不知道什么是NPM。只想写CSS和JS脚本,老实说,你可能可以考虑使用类似three.JS的东西,而不是忍受WebGPU(相对而言)的冗长。比如可以使用现有的CDN将三个.js直接包含在脚本标记中(建议放入子资源SHA哈希,以保护自己免受CDN的恶意攻击)。但是如果你想使用WebGPU运行Alain Galvin的教程,或者他的示例代码中的render.ts,其实也可以通过一点小技巧处理将TypeScript转换成JavaScript。
Rust :
正如前面提到的,WebGPU最令人兴奋的优势是可以无缝地交叉编译使用它的代码,而无需更改浏览器或桌面系统。桌面系统运行的代码使用浏览器的库化版本,因此基本没有差别。
如果你想在Rust中编写WebGPU, 我建议查看wgpu项目中的官方教程(https://sotrh.github.io/learn-wgpu/),或wgpu源代码库中的示例(https://github.com/gfx-rs/wgpu/tree/trunk/wgpu/examples/)。在桌面上使用Rust WebGPU实际上比在浏览器中使用要容易得多;这些库在web上大多运行良好,但Rust-to-wasm的构建体验仍然还不够好。我在这里找到了一个很好的wasm pack教程(https://developer.mozilla.org/en-US/docs/WebAssembly/Rust_to_wasm). 不过大多数Rust on web的开发人员似乎都在使用一种名为“Trunk”(https://trunkrs.dev/)的东西。它作为前端似乎解决了我对wasm pack的所有不满。
我也有一个为WebGPU制作的Rust repo示例(https://github.com/mcclure/rs-hello),示例没有附带构建脚本,非常基础,只是一个“Hello,三角形”的示例,但添加了Cargo.toml。它确实提供了针对web的单行构建指令,并且当在桌面上运行时,它可以最大限度地减少磁盘使用。(当在没有WebGPU的情况下在网络上运行时,它还会打印一条错误消息,而wgpu示例没有。)可以点击这里(https://data.runhello.com/j/wgpu/2/)看到此示例的编译表单。
C++ :
对于使用C++的程序员,可以使用“Dawn”库。我还没有接触过这个,但这里有一个非常详细的Dawn C++教程/介绍(https://eliemichel.github.io/LearnWebGPU/),有兴趣可以看一下。
一些自已的想法:
我有一个着奇怪的白日梦:如果有一个名为Rust-GPU的实验项目可以将Rust编译为SPIR-V就好了。从SPIR-V到WGSL的编译器已经存在,因此原则上应该也已经可以在Rust中编写WebGPU着色器,只差能将各组件整合在一起的构建工具。我确实觉得,WGSL对类似C++这样有中断机制的动态语言使用着色器语言造成了障碍,但Rust非常擅长复杂的预构建处理,所以只要你不是在动态构建着色器,那么就很容易。
我想对于一个纯Rust的程序,某些函数可以被标记为编译到着色器,这样就可以在着色器和CPU代码之间共享数学函数,或者可以根据性能考虑在CPU计算和GPU着色之间切换。我有一个现有的项目使用计算着色器,为了解释在CPU上还是在着色器中计算更快的问题,代码包括两个对比,需要写复杂的框架代码来处理来回切换。这一切其实都应该是自动的。我喜欢用Rust编写低层的引擎代码,而更喜欢使用TypeScript编写业务逻辑代码。在浏览器中,我已经可以混合使用Rust和TypeScript,网络上也有大量的示例代码。如果使用WGPU作为图形引擎,应可以加入Servo或QuickJS或其他东西编写一个跨平台程序,以TypeScript的形式在浏览器中运行,内置wasm bindgen Rust,或者基于Rust开发内置TypeScript解释器在桌面上运行。我想创建一个小型的网络游戏引擎,它既有Electron的所有优点,也许可以用Tauri(https://tauri.app/)做同样的事情。
除此之外是不是还有其它可能性?WebGPU的规范可以作为机器可解析的WebIDL文件使用会让为Lua生成绑定变得容易吗?既然可以将Rust编译到WGSL,是否能编写一个包含着色器的纯Rust程序,把TypeScript或AssemblyScript编译到WGSL,从而生成一个包括着色器的纯TypeScript程序吗?既然不关心用哪种语言编写,为什么不走另一条路呢?比如使用WGSL编写LLVM,将其编译为原生+wasm的东西,或者在WGSL中编写包括着色器在内的整个程序。如果w3觉得WGSL如此出色,那为什么不搞起呢?
译者简介:
卞安,知名引擎技术专家,CSDN博客专家,从事游戏研发工作近二十年,曾担任过多家知名企业引擎总监和技术专家,目前致立于引擎工具及IDE方面的独立研发,作品《PyMe一站式开发工具》。
推荐阅读:
这里是一个专注于游戏开发的社区,我们致力于为广大游戏爱好者提供一个良好的学习和交流平台。我们的专区包含了各大流行引擎的技术博文,涵盖了从入门到进阶的各个阶段,无论你是初学者还是资深开发者,都能在这里找到适合自己的内容。除此之外,我们还会不定期举办游戏开发相关的活动,让大家更好地交流互动。加入我们,一起探索游戏开发的奥秘吧!
更多推荐
所有评论(0)