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、光照


五、总结


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

  • 坐标系转换
  • 参数方程(圆锥曲线、贝塞尔曲线(二、三阶))
  • 向量(叉乘、点乘)
  • 矩阵
相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
相关文章
|
1月前
|
Apache 图形学
WebGL☀️Unity WebGL适配到各平台的教程
WebGL☀️Unity WebGL适配到各平台的教程
|
11月前
|
存储 缓存 前端开发
WebGL简介
WebGL简介
106 0
WebGL简介
|
移动开发 资源调度 JavaScript
【Three.js】入门教程
【Three.js】入门教程
216 0
|
存储 JavaScript 索引
《WebGL 3D 开发实战详解 第 2 版》学习笔记
《WebGL 3D 开发实战详解 第 2 版》学习笔记!!!《WebGL 3D 开发实战详解 第 2 版》学习笔记!!!
《WebGL 3D 开发实战详解 第 2 版》学习笔记
|
存储 前端开发 JavaScript
WebGL 基础概念
WebGL 基础概念
137 0
WebGL 基础概念
|
移动开发 JavaScript 前端开发
Three.js 入门指南
Three.js 是一个 JavaScript 库,用于在 Web 浏览器中创建 3D Web 图形。
559 0
Three.js 入门指南
|
前端开发 JavaScript 异构计算
WebGL基础笔记
WebGL基础笔记
183 0
|
监控 前端开发 索引
如何用webgl(three.js)搭建一个3D库房,3D密集架,3D档案室,-第二课
闲话少叙,我们接着第一课继续讲(http://www.cnblogs.com/yeyunfei/p/7899613.html),很久没有做技术分享了。很多人问第二课有没有,我也是抽空写一下第二课。 第一课程提到了在库房的基础上添加上下架 消防 温湿度等等控制 刚好 最近有接到一个客户的需求 是和库房...
2213 0
|
算法 JavaScript
如何用webgl(three.js)搭建一个3D库房-第一课
今天我们来讨论一下如何使用当前流行的WebGL技术搭建一个库房并且实现实时有效交互 第一步、搭建一个3D库房首先你得知道库房长啥样,我们先来瞅瞅库房长啥样(这是我在网上找的一个库房图片,百度了“库房”一下,找不到合适的全景,我们也只能窥一斑思全豹了,就它了,特此声明:此图片归原作者所有 非本人所拍,...
2824 0
|
存储 前端开发 JavaScript
WEBGL学习【八】模型视图投影矩阵
版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/78473425 ...
1074 0