webgl系列之 buffer的使用

发表于 2年以前  | 总阅读数:503 次

大家好,好久没有用心写文章了,还是勿忘初心,砥砺前行,争取帮助大家「入门webgl,」 然后呢我自己也深度学习下,不想做three.js 的api 调用者,路漫漫其修远兮,吾将上下而求索。读完本篇文章,你可以学到什么,或者日后你查阅资料可以查看, 记得点赞、收藏

  1. Webgl 中的buffer 到底是什么???
  2. 为什么要有buffer这东西, 没有不行吗???
  3. 如何使用webgl 中的buffer???

数学??

听到webgl 这个三个字, 很多同学就怕难, fly哥我数学不好, 我学不好???别慌,不会就多思考, 别做说话的巨人,行动的矮子。

数学差

这一次还是手把手把简单的概念讲清楚,不熟悉的同学可以先复习下这篇文章。

这一篇文章:[几个简单的小例子 带你入门webgl]

什么是buffer

buffer, 这是啥东西啊 ,或者说为什么要有buffer 这个东西 对于webgl 来说。我们先看下官方定义:

「WebGLBuffer」 接口属于 WebGL API 的一部分,表示一个不透明的缓冲区对象,储存诸如顶点或着色之类的数据。

官方的这个解释,作为一个小白来说, 啥哇,你这是在为难我胖虎嘛???

为难我胖虎

没事由我来大家解读,首先第一句话就是一句废话, 属于「webgl API 的一部分」, 这我他的也知道哇,我们重点分析 一下这句话,是一个不透明的缓冲区对象,

什么是缓冲区对象

「webgl提供一种很方便的机制 ,就是缓冲区对象」,它可以一次性向着色器传入多个顶点的数据。缓冲区对象是WebGL系统中的一块内存区域,我们可以一次性地向缓冲区对象中填充大量的顶点数据,然后将这些数据保存在其中,供顶点着色器使用。

确实是很方便机制,为什么这么说呢, 我就拿 画3个点的 这个例子 去做说明, 「下面写的都是伪代码」

没用缓冲区

我想在webgl 中画3个点, 很简单吧 ,不搞一些花里胡哨的,就简单的3个点:

  // 清除颜色缓冲区
  gl.clear(gl.COLOR_BUFFER_BIT);
  const len = g_poiont.length;
  for(var i = 0; i<len; i++){//循环添加点
      //将点的位置传递到变量中a_position
      gl.vertexAttrib3f(a_Position,g_poiont[i].x,g_poiont[i].y,0.0);
      //绘制点
      gl.drawArrays(gl.POINTS,0,1);
  }

这里的画 我对这段代码做一个简单的说明

  1. 「清楚颜色缓冲区」
  2. 「然后循环遍历 数组列表」
  3. 「位置传递到顶点着色器, 然后去绘制顶点」

看不懂的话也没关系,我在后面的webgl 系列会一步一步讲解,「本篇还是文章的重点还是在buffer 的理解」, 希望小伙伴们明白,看不明白没关系。

这里的话主要介绍下gl.drawArrays 这个「api」, 理解这个api十分重要,建议多思考。

这是一个强大的api, 用来绘制各种图形,我们看下下面这张图:

api 展示图

  1. 第一个参数其实呢就是webgl绘制的方式, 有点、线、三角形 .... 我们这里是采用的绘制点的方式
  2. 第二参数:就是从哪个顶点绘制参数
  3. 第三个参数:当前绘制需要用 几个顶点

因为我们是在循环中,所以呢就是每一次循环,绘制一个顶点 。也就是在程序运行的时候,顶点着色器运行一次, 因为我们也只绘制一个点对吧, 好像看着还挺好的哇,合情合理。

我们看下下面这张图:

image-20220115141239602

上面这张图是一个哆唻A梦的3维网格模型,从图像中去看,他的顶点有很多,我们难道要用循环一次一次 就去画出这个顶点嘛,那这样 gpu 渲染会快嘛, 肯定不是这么搞的, 这时候你再去读一下上面的「buffer」 定义:「它可以一次性向着色器传入多个顶点的数据」

我们使用buffer的方式再去绘制3个顶点:

使用缓冲区

我们看下伪代码:

 //设置顶点位置
 initVertexBuffers(gl);
 //将三个点绘制出来
 gl.drawArrays(gl.POINTS,0,3);
  1. 第一个函数使用了 使用了buffer, 并且做了数据绑定
  2. 然后我们告诉webgl 我们当前绘制 3个顶点,并且数据啥的 我们已经在缓冲中绑定好了

这样对于各种复杂的模型,我们都可以轻易拿捏,真的很帅哇, 一次性可以处理 很多个顶点,充分发挥GPU「并行渲染」的能力。

我画了一个流程对比图,方便你理解

使用了缓冲区对象

没有使用缓冲区对象的顶点着色器 可能会根据顶点的个数执行多次

未使用顶点着色器对象

好了到下面一个问题了到底如何使用缓冲区的呢????

如何使用缓冲区

其实就是刚才上面的「initVertexBuffers」函数做的几件事

  1. 第一步:创建缓冲区对象(gl.createBuffer())
  2. 第二步:绑定缓冲区对象(gl.bindBuffer())
  3. 第三步:将数据写入缓冲区对象(gl.bufferData())
  4. 第四步:将缓冲区对象分配给一个attribute变量(gl.vertexAttribPointer())
  5. 第五步:开启attribute变量(gl.enableVertexAttribArray())

跟着我的脚步一步一步来分析:

创建缓冲对象

代码其实很简单 就是下面这一行:

const buffer = gl.createBuffer()

但是他实际会发什么呢, 如图所示:

展示

其实在内存中就会分配一块缓冲区对象,有创建其实就有对应的 删除缓冲区对象

const buffer =  gl.createBuffer()
gl.deleteBuffer(buffer)

绑定缓冲区对象

有了对象了,我们要开始绑定缓冲区对象, 细心的同学看上面图片 可能会发现 在缓冲区的上面 「gl.ARRAY_BUFFER」 还有 「gl.ELEMENT_ARRAY_BUFFER」 这两个有什么区别呢???什么时候使用呢

就是因为buffer 的类型很多变, 所以你必须手动绑定,表示当前buffer

我先介绍下 这两个buffer 的区别:

  1. gl.ARRAY_BUFFER: 包含顶点属性的Buffer,如顶点坐标,纹理坐标数据或顶点颜色数据。
  2. gl.ELEMENT_ARRAY_BUFFER: 用于元素索引的Buffer。
  3. 当使用 「WebGL 2 context」

时,可以使用以下值:

  • gl.COPY_READ_BUFFER: 从一个Buffer对象复制到另一个Buffer对象。
  • gl.COPY_WRITE_BUFFER: 从一个Buffer对象复制到另一个Buffer对象。
  • gl.TRANSFORM_FEEDBACK_BUFFER: Buffer for transform feedback operations.
  • gl.UNIFORM_BUFFER: 用于存储统一块的Buffer。
  • gl.PIXEL_PACK_BUFFER: 用于像素传输操作的Buffer。
  • gl.PIXEL_UNPACK_BUFFER: 用于像素传输操作的Buffer。

这里不理解的话没关系,后面会讲, 你只要知道,buffer有很多类型, 因为我们是顶点嘛, 所以绑定的肯定是第一个类型

代码如下:

const canvas = document.getElementById('canvas');
const gl = canvas.getContext('webgl');
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);

然后看下下面的图片,

绑定缓冲区对象

注意看小箭头, 箭头就是绑定buffer的过程

写入数据到缓冲对象了

这时候我们的前置工作都已经准备好了, 那么数据呢如何写进去呢,在这之前我先简单讲一个数据类型——类型数组

类型数组:

JavaScript类型化数组是一种类似数组的对象,并提供了一种用于访问原始二进制数据的机制。正如你可能已经知道,Array 存储的对象能动态增多和减少,并且可以存储任何JavaScript值。JavaScript引擎会做一些内部优化,以便对数组的操作可以很快。然而,随着Web应用程序变得越来越强大,尤其一些新增加的功能例如:音频视频编辑,访问WebSockets的原始数据等,很明显有些时候如果使「用JavaScript代码可以快速方便地通过类型化数组来操作原始的二进制数据将会非常有帮助。」

但是,不要把类型化数组与正常数组混淆,因为在类型数组上调用 Array.isArray() 会返回false。此外,并不是所有可用于正常数组的方法都能被类型化数组所支持(如 push 和 pop)。

为了优化性能,webgl需要同时处理大量相同类型的数据, 例如顶点的坐标 和顶点的颜色。浏览器事先知道数组的类型,处理起来更高效, 有的强类型的感觉。

类型数组

所以代码如下:

 // 三角形的顶点数据
  const vertices = new Float32Array([0.0,0.5,-0.5,-0.5,0.5,-0.5]);
 //创建缓冲区对象
  const vertexBuffer = gl.createBuffer();
  if(!vertexBuffer){
      console.log("创建缓冲区对象失败");
      return -1;
  }

  //将缓冲区对象绑定到目标
  gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer);

  //向缓冲区对象中写入数据
  gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);

最后一步就是我们的绑定数据, 我们来一起解读下这个「api」 「将 第二个参数数据绑定到第一个参数的缓冲区对象中」,第三个参数表示什么呢???, 表示的向缓冲区对象写入一次数据,但是需要绘制很多次

如图:

写入数据

分配变量

现在数据也写入缓冲区中了, 然后就是分配变量。这里其实也是只有两步

  1. 第一步其实 从着色器找出属性 对应的位置
  2. 然后将缓冲区对象分配给这个变量

我们先看下代码:

 //获取attribute变量的存储位置
  const a_Position = gl.getAttribLocation(gl.program, "a_Position");
  if(a_Position < 0){
      console.log("无法获取变量的存储位置");
      return;
  }

  //将缓冲区对象分配给a_Position变量
  gl.vertexAttribPointer(a_Position,2,gl.FLOAT,false,0,0);

前半部分其实 这里的话会有一点前置小知识, 会在后面文章讲解, 主要是创建 webgl 程序, 然后会初始化着色器程序, 同时在顶点着色器中 其实就是一段 字符串中 ,有「a_Position」 这么一部分,然后我通过gl.getAttribLocation 去查找到这个 变量 对应的存储位置。

后半部分的话其实:就是将缓冲区的对象 分配给这个变量 ,我们看下这个api 「gl.vertexAttribPointer」

  1. 第一个参数的话其实 指定要修改的顶点属性的索引, 而这个索引 就是我们通过上面在顶点着色器中去查找到的
  2. 第二参数 的表示 指定每个顶点属性的组成数量,必须是1,2,3或4。这是为什么呢 ,因为顶点坐标 默认是(x,y,z,w)如果你选择是1 那么 程序会帮你把剩下的参数补充。2 3 设置为0 4 设置为 1 。因为我们这里 其实就是个二维坐标 , 所以只用到了 x,y 这样的坐标 所以是2
  3. 第三个 表示数据类型, 我们这里是浮点型
  4. 第四个 表示归一化 ,就是把 非浮点型的数据 归一到 【0,1】 或者 是【-1,1】 区间
  5. 第五个 表示相邻两个顶点之间的字节数
  6. 最后一个 表示 我们获取的这个顶点索引 是在缓冲区 的何处 开始存储的 , 我们缓冲区对象 存的都是顶点数据, 所以这里是0

详细文档仔细的话, 可以去MDN 查看。一个参数 6个参数,所以学习webgl 真的很有挑战哇, 「不过还是那句话, 大家觉得难,你学会了 你的市场价值就体现了」。还是一个字 冲冲!!!

看下图片

此时的场景

激活

有人看到上面图片就说, 数据也写入了, 也进行变量分配了, 为啥中间有一段连线是断的呢???webgl 是真的狗, 搞得是真的复杂,我这就想画了3个点, 搞了 好几步。头疼哇,「所以说three.js 这种框架 设计 不得不说 一个字牛逼 ,但是为了学习, 我还是要学习原理, 对于three.js 你才能轻松驾驭」

我们看下怎么激活的 就一行代码

 //链接a_Position变量与分配给它的缓冲区对象
  gl.enableVertexAttribArray(a_Position);

其实就是这么简单的一行代码,表示开启变量 , 同时建立了 缓冲区对象 和 attribute 之间的链接了

看下图片:

链接

总结

这是今年Webgl 系列的第一篇文章主要讲解了buffer 从 what 、 how 、 why 三个方面去阐述了 ,今年的文章都是以系列的模式去展示给大家, 最后我用文字进行总结下知识点

  1. 「第一步:创建缓冲区对象(gl.createBuffer())」
  2. 「第二步:绑定缓冲区对象(gl.bindBuffer())」
  3. 「第三步:将数据写入缓冲区对象(gl.bufferData())」
  4. 「第四步:将缓冲区对象分配给一个attribute变量(gl.vertexAttribPointer())」
  5. 「第五步:开启attribute变量(gl.enableVertexAttribArray())」

最后再来一张图加深 同学们的记忆, 序号都标的好好的,

序号图

最后点个赞和在看吧, 让更多的看到,也欢迎加我的微信和我一起交流, 我们下期再见了了

本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/8vBBTD61_ad1iyZDOnoFJg

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 5年以前  |  237228次阅读
vscode超好用的代码书签插件Bookmarks 2年以前  |  8063次阅读
 目录