文章目录

  • WebGL、canvas、svg
    • 面试题
    • canvas
      • 面试题
      • canvas位图和svg矢量图的区别
      • canvas的绘图原理
      • canvas.style.width和canvas.width区别
    • WebGL
      • 基本概念
        • 着色器获取数据的四种方式
      • 案例:原生WebGL API绘制三角形
      • 图形绘制流水线 渲染管线

WebGL、canvas、svg

面试题

canvas

canvas只需要操作一个canvas标签,使用JavaScripy指令进行动态绘图。 Canvas 可以做到像素级操作,例如图片滤镜效果等,由于绘制的是位图,所以缩放会导致失真。

面试题

  • canvas导出图片模糊原因 如何解决,restore和save的区别
  • canvas位图和svg矢量图的区别
  • canvas的绘图原理,canvas 渲染原理
  • canvas.style.width和canvas.width区别
  • canvas怎么进行图片压缩的

canvas位图和svg矢量图的区别

canvas svg webGL
2D 2D 3D
不会保留绘制的图形的信息,基于像素点绘制位图,放大会会失真 内存中保留绘制的图形的信息,用html标签描绘形状,矢量图放大不会失真
canvas无法对已经绘制的图像进行修改、操作 svg中每个图形又对应真实的dom节点、svg可以获取到标签进行操作
高数据量高绘制频率(帧率)的场景,如动画、游戏 低数据量低绘制频率的场景,如图形、图表

矢量图为时间换空间,位图为空间换时间
差不多的条件下,矢量图耗费CPU多,位图耗费内存多一点

canvas的绘图原理

canvas.style.width和canvas.width区别

  • canvas.width / canvas.height 表示画布真实大小,其实我们并不可见,canvas绘制是以画布实际大小展开的
  • canvas.style.width / canvas.style.height 表示画布输出到浏览器我们可见的/最终的大小

WebGL

什么是webGL
webGL是一种帮助我们开发3D网页的绘图技术,底层是JavaScript API

WebGL 技术旨在帮助我们在不使用插件的情况下在任何兼容的网页浏览器中开发交互式 2D 和 3D 网页效果

基本概念

WebGL 只关心两件事:裁剪空间中的坐标值和颜色值

WebGL运行在电脑的GPU上,运行在GPU上的代码需要提供成对的方法。每对方法中有 顶点着色器 + 片元着色器

  • 顶点着色器:计算顶点的位置,提供顶点在裁剪空间中的坐标值
  • 片元着色器:计算图元的颜色值,基于顶点着色器的计算结果绘制像素点

着色器获取数据的四种方式

  • 属性和缓冲

    • 缓冲是发送到GPU的一些二进制数据序列。通常缓冲数据包括位置、方向、纹理坐标、顶点颜色值等。
    • 属性说明如何从缓冲中获取所需数据并将它提供给顶点着色器
  • 全局变量:在着色程序运行之前赋值,在运行过程中全局有效。全局变量在一次绘制过程中传递给着色器的值都一样。
  • 纹理是一个数据序列,可以在着色程序运行中随意读取其中的数据。一般情况下我们在纹理中存储的大都是图像数据,但你也可以根据自己喜欢存放除了颜色数据以外的其它数据
  • 可变量是一种顶点着色器给片元着色器传值的方式

案例:原生WebGL API绘制三角形

GPU上的工作:

  1. 先调用三次顶点着色器计算出三角形的3个顶点在裁剪空间坐标系中的对应位置。 通过变量 gl_Position保存在GPU中
  2. 调用片元着色器完成每个顶点颜色值的计算,通过变量gl_FragColor 将对应的颜色值存储在 GPU 中
  3. 完成这些工作后我们已经得到了绘制三角形所需的像素点,最后便是光栅化三角形了。

WebGL 作为一种 3D 绘图技术本身就是依托于 HTML5 中的 canvas 元素而存在的

  1. 首先我们需要创建一个 canvas 元素作为绘制三角形所需的画布,并完成浏览器对 canvas 元素兼容性的测试。
function webglInit () {const canvasEl = document.createElement('canvas'); // canvas 元素创建canvasEl.width = document.body.clientWidth; // 设置 canvas 画布的宽度canvasEl.height = document.body.clientHeight; // 设置 canvas 画布的高度document.body.append(canvasEl); // 将创建好的 canvas 画布添加至页面中的 body 元素下// 接下来我们需要判断浏览器对于 WebGL 的兼容性,如果浏览器不支持 WebGL 那么我们就不需要再进行下去了if(!canvasEl.getContext("webgl") && !canvasEl.getContext("experimental-webgl ")) {alert("Your Browser Doesn't Support WebGL");return;}// 如果浏览器支持 WebGL,那么我们就获取 WebGL 的上下文对象并复制给变量 glconst context = (canvasEl.getContext("webgl"))? canvasEl.getContext("webgl") : getContext("experimental-webgl");/* 设置视口 context.viewport(x, y, width, height);x: 用来设定视口的左下角水平坐标。默认值:0y: 用来设定视口的左下角垂直坐标。默认值:0width: 用来设定视口的宽度。默认值:canvas 的宽度height: 用来设定视口的高度。默认值:canvas 的高度当你第一次创建 WebGL 上下文的时候,视口的大小和 canvas 的大小是匹配的。然而,如果你重新改变了canvas的大小,你需要告诉 WebGL 上下文设定新的视口,因此这里作为初次创建这行代码可以省略*/context.viewport(0, 0, context.canvas.width, context.canvas.height);return context;
}
  1. 需要准备画三角形所需的顶点即顶点着色器,以及三角形对应的填充色即片元着色器
const gl =  webglInit();
// 创建顶点着色器 语法 gl.createShader(type) 此处 type 为枚举型值为 gl.VERTEX_SHADER 或 gl.FRAGMENT_SHADER 两者中的一个
const vShader = gl.createShader(gl.VERTEX_SHADER)
// 编写顶点着色器的 GLSL 代码 语法 gl.shaderSource(shader, source); shader - 用于设置程序代码的 webglShader(着色器对象) source - 包含 GLSL 程序代码的字符串
gl.shaderSource(vShader, `attribute vec4 v_position;void main() {gl_Position = v_position; // 设置顶点位置}
`)
gl.compileShader(vShader) // 编译着色器代码const fShader = gl.createShader(gl.FRAGMENT_SHADER)
gl.shaderSource(fShader, `precision mediump float;uniform vec4 f_color;void main() {gl_FragColor = f_color; // 设置片元颜色}
`) // 编写片元着色器代码
gl.compileShader(fShader) // 编译着色器代码
  1. 就需要创建一个程序用来连接我们的顶点着色器和片元着色器完成最终的三角形绘制工作。
// 创建一个程序用于连接顶点着色器和片元着色器
const program = gl.createProgram()
gl.attachShader(program, vShader) // 添加顶点着色器
gl.attachShader(program, fShader) // 添加片元着色器
gl.linkProgram(program) // 连接 program 中的着色器gl.useProgram(program) // 告诉 WebGL 用这个 program 进行渲染const color = gl.getUniformLocation(program, 'f_color')
// 获取 f_color 变量位置
gl.uniform4f(color, 0.93, 0, 0.56, 1) // 设置它的值const position = gl.getAttribLocation(program, 'v_position')
// 获取 v_position 位置
const pBuffer = gl.createBuffer()
// 创建一个顶点缓冲对象,返回其 id,用来放三角形顶点数据,
gl.bindBuffer(gl.ARRAY_BUFFER, pBuffer)
// 将这个顶点缓冲对象绑定到 gl.ARRAY_BUFFER
// 后续对 gl.ARRAY_BUFFER 的操作都会映射到这个缓存
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0.5,0.5, 0,-0.5, -0.5
]),  // 三角形的三个顶点// 因为会将数据发送到 GPU,为了省去数据解析,这里使用 Float32Array 直接传送数据
gl.STATIC_DRAW // 表示缓冲区的内容不会经常更改
)
// 将顶点数据加入的刚刚创建的缓存对象gl.vertexAttribPointer( // 告诉 OpenGL 如何从 Buffer 中获取数据position, // 顶点属性的索引2, // 组成数量,必须是 1,2,3 或 4。我们只提供了 x 和 ygl.FLOAT, // 每个元素的数据类型false, // 是否归一化到特定的范围,对 FLOAT 类型数据设置无效0, // stride 步长 数组中一行长度,0 表示数据是紧密的没有空隙,让 OpenGL 决定具体步长0 // offset 字节偏移量,必须是类型的字节长度的倍数。
)
gl.enableVertexAttribArray(position);
// 开启 attribute 变量额,使顶点着色器能够访问缓冲区数据gl.clearColor(0, 1, 1, 1) // 设置清空颜色缓冲时的颜色值
gl.clear(gl.COLOR_BUFFER_BIT) // 清空颜色缓冲区,也就是清空画布
// 语法 gl.drawArrays(mode, first, count); mode - 指定绘制图元的方式 first - 指定从哪个点开始绘制 count - 指定绘制需要使用到多少个点
gl.drawArrays( gl.TRIANGLES, 0, 3 )

作者:政采云前端团队
链接:https://juejin.cn/post/6994940475459731463
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

图形绘制流水线 渲染管线

GPU 接收 CPU 的指令进行图形的绘制,通过顶点处理和片元处理等操作,生成像素阵列输入到帧缓存。

图形的渲染流程,称为渲染管线。
渲染管线主要包括两个功能
1.将物体3D坐标转变为屏幕空间2D坐标
2.为屏幕每个像素点进行着色

几何顶点被组合为图元(点,线段或多边形),然后图元被合成片元,最后片元被转换为帧缓存中的象素数据。

顶点处理:对顶点进行坐标变化

图元组装和裁剪:图元组装是指将顶点组合生成一个个图元(点/线/三角形),裁剪是指将视口之外的对象进行裁剪,裁剪针对的是逐个片元而不是逐个顶点。

光栅化:光栅化是将几何图元变为二维图像的过程。
该过程包含了两部分的工作。
第一部分工作:决定窗口坐标中的哪些整型栅格区域被基本图元占用;
第二部分工作:分配一个颜色值和一个深度值到各个区域。光栅化过程产生的是片元。

二维图象上每个点都包含了颜色、深度和纹理数据。将该点和相关信息叫做一个 片元(fragment)。片元比像素多了许多信息。

片元处理:该阶段主要是通过片元着色器来计算片元的最终颜色和深度值,同时通过深度测试和模板测试来判断当前片元是否可见,如果片元通过测试,那它就可以被直接绘制到帧缓存中了。

WebGL、canvas、svg相关推荐

  1. svg放大缩小拖动_Day2 三种图表技术SVG、Canvas、WebGL 3D比较

    1.什么是SVG? 描述: 一种使用XML描述的2D图形的语言 SVG基于XML意味着,SVG DOM中的每个元素都是可用的,可以为某个元素附加Javascript事件处理器. 在 SVG 中,每个被 ...

  2. HTML5 Canvas、内联 SVG、Canvas vs. SVG

    canvas 元素用于在网页上绘制图形. 什么是 Canvas? HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像. 画布是一个矩形区域,您可以控制其每一像素. canv ...

  3. 【前端】CSS3、Canvas、SVG等5种方式实现水波纹波浪动画特效

    目录 一.CSS3动画+图片波浪效果 1. 效果图 2. 代码 3. 原理 二.纯CSS3圆盘波浪进度效果 三.纯CSS3涟漪效果 四.Canvas波浪效果 五.SVG+jQuery波浪效果 六.源码 ...

  4. SVG、canvas、绘制线段和填充多边形、矩形、曲线的绘制和填充

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 目录 文章目录 1.了解网页中的两个绘图技术 (1)SVG (2)canvas (3)画布的尺寸和坐标 2.绘制线段和填充多 ...

  5. 平面图之HTML5、Canvas、SVG

    最近项目里遇上一楼宇画平面图,暂时还没什么想法,希望园子里的大虾和牛人们多指教.多指点.谈谈建议和想法也行.能深入到技术实现层面最好不过了,在此先谢过各位了!下面大致简单说下我项目里关于这一块的业务. ...

  6. 微信小程序(数据可视化、Canvas、绘制线段、图形、太极图、文本、图像、渐变、变形)

    一.数据可视化 1数据可视化概述 数据可视化Data Visualization:就是指将结构或非结构数据转换成适当的可视化图表,然后将隐藏在数据中的信息直接展现于人们面前. 2应用场景 数据报表 特 ...

  7. Android 中一些常用类的常用方法(Math、Random、Color、Paint、Canvas、Bitmap、BitmapFactory)...

    1.java.lang.Math类常用的常量和方法: Math.PI 记录的圆周率 Math.E 记录e的常量 Math.abs 求绝对值 Math.sin 正弦函数 Math.asin 反正弦函数 ...

  8. Android Paint、Canvas、Matrix使用讲解(一、Paint)

    http://blog.csdn.net/tianjian4592/article/details/44336949 好了,前面主要讲了Animation,Animator 的使用,以及桌面火箭效果和 ...

  9. Paint、Canvas、Matrix使用讲解(一、Paint)

    好了,前面主要讲了Animation,Animator 的使用,以及桌面火箭效果和水波纹效果,分别使用android框架和自己绘制实现,俗话说,工欲善其事,必先利其器,接下来几篇文章主要讲绘制中我们需 ...

最新文章

  1. Android 实现一个验证码倒计时(Handler postDelayed 实现验证码倒计时)
  2. 面试官问:消息被重复消费,怎么避免?有什么好的解决方案?
  3. laravel5.7的redis配置,一直报错Class 'Predis\Client' not found
  4. 一直认为 count(1) 比 count(*) 效果高,被同事鄙视了。
  5. fastjson的@JSONField注解
  6. MyBatis二级缓存的配置
  7. mysql 中 end like,MySQL 这三道必问面试题,你都会吗?
  8. Java SimpleTimeZone setStartRule()方法与示例
  9. java 后台自动刷新请求_spring oauth2+JWT后端自动刷新access_token
  10. 深入了解C++变量类型有哪些
  11. D3D中材质通过D3DMATERIAL9结构说明
  12. 部署Ansible与常用模块
  13. 5.4.1. Check Constraints
  14. python生成3d人体模型_make human开源3D人体建模软件免费下载|make human开源3D人体建模软件2018最新版下载_v1.0.2_9号软件下载...
  15. 活码二维码(动态二维码)域名池介绍
  16. template标签的用法总结
  17. mysql安装配置cmd_mysql安装配置
  18. css设置始终显示滚动条
  19. 表格 + 分页 +表格上编辑
  20. Bilibili高可用架构【B 站在云+社区沙龙分享干货】

热门文章

  1. 看完《天狗》,我对社会充满了失望
  2. python游戏背景音乐循环_Python:pygame游戏编程之旅六(游戏中的声音处理)
  3. Python之闰年算法
  4. 我是手游开发者(三)客户端与服务器时间同步问题
  5. python输出反三角形_Python实现输出“倒三角形”
  6. 从初稿到精品:论文校对软件的技术进步与应用
  7. 芭比linux安装硬盘,可爱的小芭比……Debian下为移动硬盘装上puppy(使用GRUB引导)...
  8. easycms php7.1,cmseasy sql注入漏洞(无视防御)
  9. 测试——白盒测试与黑盒测试
  10. 三十二、ARP协议、DHCP协议、ICMP协议