仓库源文站点原文


title: WebGL 基础概念学习摘要(上) layout: post thread: 213 date: 2019-02-01 author: Joe Jiang categories: Document tags: [2019, WebGL, GLSL, 可视化] excerpt: 翻阅 WebGL Fundamentals 时碎碎记录下 WebGL 基础概念一些细节。


一、概念基础

WebGL 实质上是一个光栅化引擎,根据你的代码绘制出点,线和三角形。

WebGL 每次绘制需要两个着色器, 一个顶点着色器和一个片断着色器,每一个着色器都是一个方法。 一个顶点着色器和一个片断着色器链接在一起放入一个着色程序中(或者只叫程序)。一个典型的 WebGL 应用会有多个着色程序。

// vec2, vec3和 vec4分别代表两个值,三个值和四个值
vec4 a = vec4(1, 2, 3, 4);
vec4 b = a * 2.0;
// b 现在是 vec4(2, 4, 6, 8);

// mat2, mat3 和 mat4 分别代表 2x2, 3x3 和 4x4 矩阵
mat4 a = ???
mat4 b = ???
mat4 c = a * b;

vec4 v;
// v.x 和 v.s 以及 v.r , v[0] 表达的是同一个分量。
// v.y 和 v.t 以及 v.g , v[1] 表达的是同一个分量。
// v.z 和 v.p 以及 v.b , v[2] 表达的是同一个分量。
// v.w 和 v.q 以及 v.a , v[3] 表达的是同一个分量。

v.yyyy // === vec4(v.y, v.y, v.y, v.y)
v.bgra // === vec4(v.b, v.g, v.r, v.a)
vec4(1) // === vec4(1, 1, 1, 1)
// 支持矢量调制

// 如果 v1 和 v2 都是 vec4, f 是浮点型,以下两个变量等价
vec4 m = mix(v1, v2, f);

vec4 m = vec4(
  mix(v1.x, v2.x, f),
  mix(v1.y, v2.y, f),
  mix(v1.z, v2.z, f),
  mix(v1.w, v2.w, f));

二、二维变换

对于二维变换使用 3x3 矩阵,可以快速的实现平移,旋转,缩放,单位化效果。

var m3 = {
  translation: function(tx, ty) {
    return [
      1, 0, 0,
      0, 1, 0,
      tx, ty, 1,
    ];
  },

  rotation: function(angleInRadians) {
    var c = Math.cos(angleInRadians);
    var s = Math.sin(angleInRadians);
    return [
      c,-s, 0,
      s, c, 0,
      0, 0, 1,
    ];
  },

  scaling: function(sx, sy) {
    return [
      sx, 0, 0,
      0, sy, 0,
      0, 0, 1,
    ];
  },
  identity: function() {
    return [
      1, 0, 0,
      0, 1, 0,
      0, 0, 1,
    ];
  },
};

关于如下一个矩阵计算,有两种解释方式:

projectionMat * translationMat * rotationMat * scaleMat * position

从右向左解释:首先将位置乘以缩放矩阵获得缩放后的位置,然后将缩放后的位置和旋转矩阵相乘得到缩放旋转位置,然后将缩放旋转位置和平移矩阵相乘得到缩放旋转平移位置,最后和投影矩阵相乘得到裁剪空间中的坐标。

从左往右解释:每一个矩阵改变的都是画布的坐标空间, 画布的起始空间是裁剪空间的范围(-1 到 +1),矩阵从左到右改变着画布所在的空间。

三、三维变换

gl.enable(gl.CULL_FACE);
gl.enable(gl.DEPTH_TEST);

四、动画与纹理

实现动画与 WebGL 并不直接相关,需要利用 JavaScript 随着时间改变一些值然后绘制。在此处请使用 requestAnimationFrame API.

由于纹理需要异步加载资源,所以在物体渲染上存在两种处理方式。

五、组织结构

一个 WebGL 应用推荐遵循的结构