Skip to content
Go back

Webgl的概念和示例

Updated:  at  10:14 PM

文章目录

Canvas是什么

canvas是透明的,2d坐标系统的x轴(正方向朝右)y轴(正方向朝下)

<canvas id="canvas2d" class="m-auto" width="720" height="100"> </canvas>

<script>
  var canvas = document.getElementById("canvas2d") as HTMLCanvasElement;
  if (!canvas) {
    console.log("Failed to retrieve the <canvas> element");
  } else {
    // 获取canvas上下文
    var ctx = canvas.getContext("2d");
    if (ctx) {
      // 设置填充颜色
      ctx.fillStyle = "oklch(0.769 0.188 70.08)";
      // 绘制矩形
      ctx.fillRect(0, 0, 720, 100);
    }
  }
</script>

绘制第一个3d图形

绘制三维图形与二维类似,也遵循类似的步骤,获取canvas元素、获取绘图上下文、开始绘图。

<canvas id="canvas3d" class="m-auto" width="720" height="400"> </canvas>

<script type="module">
  function canvas3D() {
    var canvas = document.getElementById("canvas3d");
    if (!canvas) {
      return console.log("Failed to retrieve the <canvas> element");
    }
    console.dir(canvas);

    // 获取webgl绘图上下文
    var gl = getWebGLContext(canvas);

    if (!gl) {
      console.log("Failed to get the redering context for WebGL");
      return;
    }

    // 指定清空canvas的颜色
    gl.clearColor(0.0, 0.5, 0.5, 1.0);

    // 清空canvas
    gl.clear(gl.COLOR_BUFFER_BIT);
  }
  canvas3D();
</script>

gl.clearColor(red, green, blue, alpha),指定绘图区域的背景色。

定义名称解释
参数red指定红色值(从0.0到1.0)
green指定绿色值(从0.0到1.0)
blue指定蓝色值(从0.0到1.0)
alpha指定透明度(从0.0到1.0)

如果任何一个分量小于0.0或者大于1.0,那么就会分别截断为0.0或1.0

一旦指定了背景色之后,背景色就会驻存在WebGL系统(WebGL System)中,在下一次调用gl.clearColor()方法前不会改变。如果将来什么时候你还想用同一个颜色再清空一次绘图区,没必要再指定一次背景色,你可以调用gl.clear()函数,用之前指定的背景色清空(即用背景色填充,擦除已经绘制的内容)绘图区域。

清空Canvas

gl.clearColor(gl.COLOR_BUFFER_BIT)清空颜色缓冲区。因为webgl的gl.clearColor继承opengl,基于多基本缓冲区模型,gl.COLOR_BUFFER_BIT代表的是颜色缓冲区。webgl还有深度缓冲区和模板缓冲区。

绘制一个点

const VSHADER_SOURCE = `
  void main() {
    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);   // 设置坐标
    gl_PointSize = 5.0;                     // 设置点的大小
  }
`;
const FSHADER_SOURCE = `
  void main() {
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // 设置点的颜色
  }
`;

let canvas = document.getElementById('drawPoint');

// @ts-ignore
var gl = window.getWebGLContext(canvas);

if (!gl) {
  console.log('Failed to gwt the rendering context for WebGL.');
  return;
}

if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
  console.log('Failed to initialize shaders.');
  return;
}

gl.clearColor(0.0, 0.0, 0.0, 1.0);  // 设置清屏颜色为黑色
gl.clear(gl.COLOR_BUFFER_BIT);      // 清除颜色缓冲区
gl.drawArrays(gl.POINTS, 0, 1);     // 设置绘制模式为点,顶点索引从0开始,共绘制1个点

顶点着色器

顶点着色器控制点的位置和大小,它用来描述顶点特性(如位置,颜色等)的程序。顶点是指二维和三维空间的一个点,比如二维或三维图形的端点或交点。

片元着色器

进行逐片元处理如光照的程序。片元是一个图形学术语,可理解为像素(图像的单元,包括这个像素的位置,颜色和其他信息)。

绘制

gl.drawArrays可用于绘制各种图形,简单介绍如下

gl.drawArrays(mode,frst,count)执行顶点着色器,按照 mode 参数指定的方式绘制图形。

参数说明类型
mode指定绘制的方式,可接收以下常量符号: gl.POINTSgl.LINES
gl.LINE_STRIPgl.LINE_LOOPgl.TRIANGLESgl.TRIANGLE_STRIPgl.TRIANGLE_FAN
枚举
first指定从哪个顶点开始绘制整型数
count指定绘制需要用到多少个顶点整型数

当程序调用g1.drawArrays()时,顶点着色器将被执行count次,每次处理一个顶点。

WebGL坐标系统

attribute变量和uniform变量

attribute变量传输的是那些与顶点相关的数据,而uniform变量传输的是那些对于所有顶点都相同(或与顶点无关)的数据。

attribute变量是一种 GLSL ES变量,被用来从外部向顶点着色器内传输数据,只有顶点着色器能使用它。为了使用 attribute 变量,需要包含以下步骤

  1. 在顶点着色器中,声明attribute变量;
  2. 将attribute 变量赋值给gl_Position变量;
  3. 向 attribute 变量传输数据。

使用js设置attribute变量画一个点

这里随意点击即可绘制一个点

const VSHADER_SOURCE = `
  attribute vec4 a_Position;
  void main() {
    gl_Position = a_Position;   // 设置坐标
    gl_PointSize = 10.0;                     // 设置点的大小
  }
`;

// ... 中间代码与上一版相同

// gl.getAttribLocation函数用于获取a_Position变量指定的attribute变量的存储地址
// 简单理解:让gl帮忙创建一个变量
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');

// ...

// 将数据(0.0, 0.0, 0.0)传给由a_Position参数指定的attribute 变量。
// 简单理解:让gl帮忙给变量赋值
gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0);   // 设置顶点位置

gl.clearColor(0.0, 0.0, 0.0, 1.0);  // 设置清屏颜色为黑色
gl.clear(gl.COLOR_BUFFER_BIT);      // 清除颜色缓冲区
gl.drawArrays(gl.POINTS, 0, 1);     // 设置绘制模式为点,顶点索引从0开始,共绘制1个点

attribute vec4 a_Position ,attribute被称为存储限定符

attribute变量都以a_前缀开始 uniform变量都以u_前缀开始 设置vec4变量时,当省略分量时,默认为1.0

gl.vertexAttrib3fgl.vertexAttrib3fv区别在于参数的接收,3f逐个接收三个参数,3fv接受一个长度为3的数组



Next Post
Promise的实现原理详解