webgl入门指南(一)

简介: 本文适合对图形感兴趣的小伙伴阅读。

一、前言


本文基于MDN技术文档:


https://developer.mozilla.org/zh-CN/docs/Web/API/WebGL_API

 

WebGL 是基于 OpenGL ES 规范的浏览器实现的JavaScript API 。能在任何兼容的Web浏览器中渲染高性能的交互式3D2D图形。
可以在HTML5 <canvas>元素中使用。


二、基于webgl的开发的库有哪些


   业界有很多基于WebGL开发了一些库,这里广东靓仔列举了一些:


基于webGL开发的库

1、three.js 开源的,功能齐全的3D WebGL库

2、RedGL 是一个开源3D WebGL库 (韩国)

3、vtk.js 是一个JavaScript库,用于在浏览器中进行科学可视

4、babylon.js 基于WebGL的图形引擎

5、Hightopo组件丰富,非开源的付费项目


Three.js的Demo图片预览

image.png

基于Three.js


三、WebGL绘制图形的5个流程


  • 创建 WebGL 上下文
  • 创建 WebGL 程序(WebGLProgram)
  • 将数据存入缓冲区
  • 将缓冲区数据读取到 GPU
  • GPU 执行 WebGL 程序,输出结果


我们来看看流程图:

image.png


   下面我们通过一个Demo来讲解下,这里看不懂的小伙伴不着急,看完Demo回头再看看,会更容易理解。


四、Demo


html
<canvas width="300" height="300"></canvas>


js

html跟Canvas2D一样,我们使用<canvas>元素就可以了

// 调用canvas元素
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
// 俩个着色器
const vertex = `
  // 将缓冲区数据读取到GPU
  attribute vec2 position;  // 声明变量名威position的二维向量
  varying vec3 color;
  void main () {
      gl_PointSize = 1.0;
      color = vec3(0.5 + position * 0.5, 0.0);
      gl_Position = vec4(position * 0.5, 1.0, 1.0);
  }
`
const fragment = `
  precision mediump float;
  varying vec3 color;
  void main () {
      // RGBA 色值表示的四维向量数据
      gl_FragColor = vec4(color, 1.0);
  }
`
// 顶点着色器  片元着色器
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertex);
gl.compileShader(vertexShader);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragment);
gl.compileShader(fragmentShader);
// 创建program并关联两个shader
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
// 启用program
gl.useProgram(program);
// 定义三个顶点,类型化数组
const points =  new Float32Array([ -1, -1, 0, 1, 1, -1,])
// 定义好的数组写入缓冲区
const bufferId = gl.createBuffer(); // 创建缓冲区对象
gl.bindBuffer(gl.ARRAY_BUFFER, bufferId); // 将缓冲区对象绑定到目标
gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW) // 将数据写入缓冲区对象
// 获取顶点着色器中的position变量的地址
const vPosition = gl.getAttribLocation(program, 'position');
// 给变量设置长度和类型
gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
// 激活这个变量
gl.enableVertexAttribArray(vPosition);
// 执行着色器完成绘制
gl.clear(gl.COLOR_BUFFER_BIT); // 清空<canvas>
gl.drawArrays(gl.TRIANGLES, 0, points.length / 2); // 绘制三角形

效果如下

image.png

demo详解

创建 WebGL直接调用 canvas 元素的 getContext 即可
将参数从2d换成webgl,代码如下:


const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl')


从效果图我们可以看到由三个顶点,绘制成一个三角形。
WebGL就是以
顶点图元来绘制几何图形的。
顶点容易理解,图元是 WebGL
可直接处理的图形单元,具体的有
7种:

gl.POINTS

线段 gl.LINES

线条 gl.LINE_STRIP

回路 gl.LINE_LOOP

三角形 gl.TRIANGLES

三角带 gl.TRIANGLE_STRIP

三角扇 gl.TRIANGLE_FAN

复杂的图形就是由这7个图元拼成的。

效果图里面三角形的颜色就是由顶点着色器、片元着色器处理的。
顶点着色器它可以改变顶点的信息,从而改变我们绘制出来的图形的形状或者大小等等。
片元着色器处理光栅化后的像素信息。
光栅化从顶点着色器和图元提取像素点给片元着色器执行代码的过程。

我们结合代码来理解这概念


顶点着色器和片元着色器代码片段

// 顶点着色器
  const vertexShader = gl.createShader(gl.VERTEX_SHADER);
  gl.shaderSource(vertexShader, vertex);
  gl.compileShader(vertexShader);
  // 片元着色器
  const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
  gl.shaderSource(fragmentShader, fragment);
  gl.compileShader(fragmentShader);


WebGLProgram 对象的创建过程主要是添加 vertexShader 和 fragmentShader,然后将这个 WebGLProgram 对象链接到 WebGL 上下文对象上

// 创建program并关联两个shader
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);


启用这个 WebGLProgram 对象

// 启用program
gl.useProgram(program);


定义好的数据写入 WebGL 的缓冲区

// 定义三个顶点,类型化数组
const points =  new Float32Array([ -1, -1, 0, 1, 1, -1,])
// 定义好的数组写入缓冲区
const bufferId = gl.createBuffer(); // 创建缓冲区对象
gl.bindBuffer(gl.ARRAY_BUFFER, bufferId); // 将缓冲区对象绑定到目标
gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW) // 将数据写入缓冲区对象

上面代码中,Float32Array,是一个类型化数组。含义即类型化数组对象描述了一个底层的二进制数据缓冲区(binary data buffer)的一个类数组视图(view)。


顶点着色器

// 将缓冲区数据读取到GPU
attribute vec2 position;  // 声明变量名position的二维向量
varying vec3 color;
void main () {
    gl_PointSize = 1.0;
    color = vec3(0.5 + position * 0.5, 0.0);
    gl_Position = vec4(position * 0.5, 1.0, 1.0);
}

attribute 表示声明变量,vec2、vec3 是变量的类型,它表示一个二维向量、三维向量,position 是变量名。


把数据绑定给顶点着色器中的 position 变量

// 获取顶点着色器中的position变量的地址
const vPosition = gl.getAttribLocation(program, 'position');
// 给变量设置长度和类型
gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
// 激活这个变量
gl.enableVertexAttribArray(vPosition);


执行着色器程序来完成绘制

// 执行着色器完成绘制
gl.clear(gl.COLOR_BUFFER_BIT); // 清空<canvas>
gl.drawArrays(gl.TRIANGLES, 0, points.length / 2); // 绘制三角形

先调用 gl.clear 将当前画布的内容清除,然后调用gl.drawArrays。gl.drawArrays里参数分别表示:

gl.TRIANGLES 表示以三角形为图元绘制、绘制的顶点偏移量、顶点数量

webgl其他知识

1、颜色

2、图案

3、纹理

3、3d(vec3三维)

4、相机

5、光照


五、总结


   在我们阅读完官方文档后,我们要深入学习,可以着重去掌握以下内容:

  • 坐标系转换
  • 参数方程(圆锥曲线、贝塞尔曲线(二、三阶))
  • 向量(叉乘、点乘)
  • 矩阵
相关实践学习
在云上部署ChatGLM2-6B大模型(GPU版)
ChatGLM2-6B是由智谱AI及清华KEG实验室于2023年6月发布的中英双语对话开源大模型。通过本实验,可以学习如何配置AIGC开发环境,如何部署ChatGLM2-6B大模型。
相关文章
|
5月前
|
传感器 机器学习/深度学习 分布式计算
卡尔曼滤波的多传感器数据融合算法
卡尔曼滤波的多传感器数据融合算法
742 0
|
图形学
Unity 3D游戏-消消乐(三消类)教程和源码
Unity 消消乐教程和源码 本文提供全流程,中文翻译。Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例) ...
6185 0
|
7月前
|
人工智能 JavaScript 前端开发
【CodeBuddy】三分钟开发一个实用小功能之:3D旋转相册
通过CodeBuddy,用自然语言描述需求即可快速实现炫酷3D相册。本文展示了从零开始构建一个可旋转的6面3D相册的过程:AI自动生成HTML骨架、CSS样式及JS交互逻辑,甚至优化性能与修复问题。无需代码基础,仅需明确需求,AI便能将想法变为现实。最终效果支持鼠标拖拽旋转、触摸操作及图片预览放大,完整代码附于文末。这一体验凸显了AI编程工具在降低技术门槛、提升开发效率方面的巨大潜力,让开发者专注于创意本身。
211 2
【CodeBuddy】三分钟开发一个实用小功能之:3D旋转相册
|
安全 前端开发 JavaScript
什么是 CSRF 攻击?如何启用 CSRF 保护来抵御该攻击?
什么是 CSRF 攻击?如何启用 CSRF 保护来抵御该攻击?
1802 5
Bully、Raft、Zab选举算法的差异比较
Bully算法、Raft算法、Zab的差与异。他们如何脱胎于Paxos而成?
604 89
|
11月前
|
移动开发 监控 关系型数据库
使用云数据库RDS和低代码开发平台“魔笔”,高效构建门户网站,完成任务领智能台灯!
使用云数据库RDS和低代码开发平台“魔笔”,高效构建门户网站,完成任务领智能台灯!
|
编解码
视频分辨率和帧率
【10月更文挑战第7天】视频分辨率和帧率
|
移动开发 监控 安全
HTML5 WebSocket详解
**WebSocket** 是一种协议,支持浏览器与服务器间的双向全双工通信。不同于传统的 HTTP 模式,WebSocket 建立持久连接,使服务器能主动向客户端推送数据。本文详细解析 WebSocket 的工作原理、优缺点及应用场景,并提供客户端和服务器端的代码示例。WebSocket 适合实时聊天、在线游戏、数据监控等场景,能显著提升用户体验和应用性能,但需注意其实现复杂性和安全性问题。
|
机器学习/深度学习 人工智能
阿里轨迹可控版Sora,告别抽卡,让视频生成更符合物理规律
【8月更文挑战第26天】阿里团队新推出的Tora视频生成模型是对先前Sora模型的重要升级。Tora通过引入轨迹控制机制,极大提升了视频中物体运动的真实性和准确性。其核心技术包括轨迹提取器、运动指导融合器及空间时间扩散变换器,共同确保视频既高质量又流畅。实验表明,Tora在清晰度、细节表现力及运动轨迹控制上均有显著进步。尽管如此,模型训练复杂度和轨迹理解能力仍有待优化。[论文](https://arxiv.org/pdf/2407.21705)
203 2
|
弹性计算 JSON 开发工具
"一键玩转阿里云ECS!Python大神揭秘:如何自动化创建镜像并跨地域复制,让你的云资源部署秒变高效达人!"
【8月更文挑战第14天】本文介绍如何使用Python与阿里云SDK自动化管理ECS镜像,包括创建镜像及跨地域复制,以优化云资源部署。首先安装`aliyun-python-sdk-ecs`并配置阿里云凭证。接着,通过Python脚本实现镜像创建与复制功能,简化日常运维工作并增强灾难恢复能力。注意权限及费用问题。
339 2