WebGPU[1] 三角形
代码见: https://github.com/onsummer/my-dev-notes/tree/master/webgpu-Notes/01-triangle
如果本篇的代码不能跑了,请联系我或自己看看文档试试修改。
2021年3月31日
入口:navigator.gpu
WebGL1 或 WebGL2 是从 canvas.getContext('webgl')
这样获取一个上下文对象来进行一切操作的。
而 WebGPU 则直接从浏览器对象中获取一个附件一样的东西:navigator.gpu
,如果你在控制台获取这玩意儿获取不到,说明你没开实验特性或浏览器压根不支持 WebGPU。
这就很像从主机里掏出一张显卡一样。
适配器 & 设备
代码最开始要从这个 gpu 对象里请求一个“适配器(adapter,是 er 不是 or)”,然后从适配器里请求一个“设备(device)”。
const adapter = await navigator.gpu.requestAdapter()
const device = await adapter.requestDevice()
适配器,指的是物理显卡。聪明的你一定能猜到,除了N卡,还有高通骁龙上面的 SoC 图形处理器,所以这个 requestAdapter()
是可以传递参数的。
设备,即把物理显卡进行逻辑对象化。当调用 requestDevice()
时,允许请求一些显卡的扩展特性,就像 WebGL 会通过请求扩展来引入额外的功能一样。
后续代码中,大量的操作均以函数调用的方式,由设备发出。这个设备对象,就类似 WebGL 的 context。区别的地方,就是“设备”它是显卡功能的集合体,更接近显卡本身,而 context 只是与显卡对话的中间人,是一个上下文对象。
休息一下!
交换链、渲染管线、WebGPU上下文、编码器
不理解 WebGPU 的渲染流程,就没办法进行下一步的。
关于交换链的描述,这里 讲得比我好。
- canvas -创建-> WebGPU上下文 -创建-> 交换链 -创建-> canvas像素内存视图(视图用于操作像素内存,辅助交换链的交换工作,将显卡上渲染好的数据写入像素内存)
- 设备 -创建-> “命令”编码器 -创建-> “渲染通道”编码器
渲染进行时,渲染通道编码器 会将 “渲染通道描述对象”,通过 交换链 绘制到 canvas 上。
编码器如何访问canvas?通过 this.swapChain.getCurrentTexture().createView()
创建出来的对象来访问 canvas 上的像素内存,把显存里绘制好的数据写入 canvas 上的像素内存。
const textureView = swapChain.getCurrentTexture().createView()
const renderPassDescriptor = {
colorAttachments: [{
attachment: textureView,
loadValue: {
r: 0.0, g: 0.0, b: 0.0, a: 1.0
}
}]
}
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor)
“命令”编码器通过传递进来的参数与交换链上的 canvas 像素内存作绑定,返回一个 “渲染通道”编码器,“渲染通道”编码器则通过设置渲染管线、调用函数来完成绘制。
passEncoder.setPipeline(pipeline)
passEncoder.draw(3, 1, 0, 0)
最后,结束此渲染通道,结束指令编码器,所有指令扔给设备。
passEncoder.endPass()
device.queue.submit([commandEncoder.finish()])
提示
若要进行代码结构优化,不想堆屎山,恭喜你,一个未来未来的架构师正在发芽,当前进度:新建文件夹。
优化的第一步,先把以下三个对象提升生命周期:
- 适配器
- 设备
- 交换链
渲染一次(帧)所需的着色器、编码器、管线和数据可能不尽一样,但是以上仨货基本不变。
现在顶点数据写死在着色器中,后续会从内存中读取并传入,类似 WebGLBuffer。
大致结构可布局如下:
const adapter = // 请求适配器
const gtx4090ti = // 请求设备
const swapChain = // 从canvas上下文中获取交换链
// 经典的 rAF
function requestNewFrame() {
const pipeline = // 创建管线
const cmdEncoder = // 创建命令编码器
const passEncoder = // 创建渲染通道编码器
/*
passEncoder 设置绘制命令
*/
// 搞定了当前帧的所有准备,提交给设备
requestAnimationFrame(requestNewFrame)
}
requestNewFrame()
或者使用异步的写法
async function init(/*参数*/) {
const adapter = await ...// 请求适配器
const gtx4090ti = await ...// 请求设备
const swapChain = // 从canvas上下文中获取交换链
const requestNewFrame = () => {
/*
创建管线、编码器,使用编码器进行绘制
*/
requestAnimationFrame(requestNewFrame)
}
return requestNewFrame
}
init(/*传参*/).then(requestFn => {
requestFn()
})
WebGPU[1] 三角形的更多相关文章
- WebGPU学习(二): 学习“绘制一个三角形”示例
大家好,本文学习Chrome->webgl-samplers->helloTriangle示例. 准备Sample代码 克隆webgl-samplers Github Repo到本地. ( ...
- WebGPU[4] 纹理三角形
代码见:https://github.com/onsummer/my-dev-notes/tree/master/webgpu-Notes/04-texture-triangle 原创,发布日 202 ...
- WebGPU图形编程(3):构建三角形图元<学习引自徐博士教程>
一.首先修改你的index.html文件 请注意主要在html页面修改添加的是需要加选择项:"triangle-list"和"triangle-strip",如 ...
- WebGPU图形编程(2):构建一个单色的三角形<学习引自徐博士教程>
非常兴奋,我坚持了下来,开始更新我的第二篇博客,还是关于WebGPU的,我在学习过程中,对这项技术非常感兴趣,即使它非常抽象,难以理解,因为我看到未来Web3D的发展,WebGPU会成为主流技术,学习 ...
- WebGPU学习(三):MSAA
大家好,本文学习MSAA以及在WebGPU中的实现. 上一篇博文 WebGPU学习(二): 学习"绘制一个三角形"示例 下一篇博文 WebGPU学习(四):Alpha To Cov ...
- WebGPU学习(六):学习“rotatingCube”示例
大家好,本文学习Chrome->webgpu-samplers->rotatingCube示例. 上一篇博文: WebGPU学习(五): 现代图形API技术要点和WebGPU支持情况调研 ...
- WebGPU学习系列目录
介绍 大家好,本系列从0开始学习WebGPU API,并给出相关的demo. WebGPU介绍 WebGPU相当于DX12/Vulkan,能让程序员更灵活地操作GPU,从而大幅提升性能. 为什么要学习 ...
- WebGPU学习(十一):学习两个优化:“reuse render command buffer”和“dynamic uniform buffer offset”
大家好,本文介绍了"reuse render command buffer"和"dynamic uniform buffer offset"这两个优化,以及Ch ...
- WebGPU学习(十):介绍“GPU实现粒子效果”
大家好,本文介绍了"GPU实现粒子效果"的基本思想,并推荐了相应的学习资料. 本文学习webgpu-samplers->computeBoids示例,它展示了如何用compu ...
随机推荐
- jest ignore
jest ignore modulePathIgnorePatterns https://jestjs.io/docs/en/configuration modulePathIgnorePattern ...
- ip/udp/tcp包 学习
/** * 以太网 */ class Ethernet { static readonly size = 14; get Destination(): string { return [ this.v ...
- 2021 NGK生态所体验好、交易快 引人注目!
据悉,NGK计划于2021年2月15日正式上线自己的生态所(时间待定),目的在于满足NGK生态建设者对于NGK几大币种的交易等需求,如NGK.BGV.SPC.USDN.VAST等.只要上NGK生态所, ...
- Baccarat如何点燃DEFI市场?
目前DeFi是成为了各大生态的"兵家必争之地",与此同时DeFi的高收益也成为吸引散户入局的一个利器.而虽然流动性挖矿板块近期的温度有所下降,但是这其中不乏还是有很多收益颇丰的De ...
- 【Azure 云服务】如何从Azure Cloud Service中获取项目的部署文件
问题描述 在历史已经部署的云服务(Azure Cloud Service)中,如何获取到项目在很久以前的部署包文件呢? 解决办法 1)如果部署云服务是通过门户上传部署包到存储账号中,则可以直接从存储账 ...
- C++Template 模版的本质
我想知道上帝的構思,其他的都祇是細節. ...
- 《Linux学习笔记:文本编辑最佳实践》
[Linux文本编辑的四种方法] 例如,要想test.txt文件添加内容"I am a boy",test.txt在当前目录中 方法一:vi编辑法 [推荐] 打开终端,输入vi t ...
- 心脏滴血(CVE-2014-0160)检测与防御
用Nmap检测 nmap -sV --script=ssl-heartbleed [your ip] -p 443 有心脏滴血漏洞的报告: ➜ ~ nmap -sV --script=ssl-hear ...
- 基于CefSharp开发浏览器(八)浏览器收藏夹栏
一.前言 上一篇文章 基于CefSharp开发(七)浏览器收藏夹菜单 简单实现了部分收藏夹功能 如(添加文件夹.添加收藏.删除.右键菜单部分功能) 后续代码中对MTreeViewItem进行了扩展,增 ...
- [Java Tutorial学习分享]接口与继承
目录 接口 概述 Java 中的接口 使用接口作为API 定义一个接口 The Interface Body 实现接口 使用接口作为类型 进化的接口 默认方法 扩展包含默认方法的接口 静态方法 接口总 ...