はじめに
WebGLで使われる最もよく使われるであろうライブラリglMatrixについて解説します。
対象のバージョンは3.4.0です。
引数を省略して、メソッドを使うことは無いようです。その方が使いやすいですね。
私が良く使うものだけを紹介します。
ベクトルは3次元のベクトルvec3を、行列は4x4の行列mat4のメソッドを紹介します。
以下の説明で使われる は代入を意味します。アルゴリズムの説明の時に見かける記号です。
ベクトルの定義
const x = vec3.create(); // 0,0,0 と初期化されます。
ベクトルを特定の値で初期化
const x = vec3.clone([1, 2, 3]); // 実引数はArray<number>でもFloat32Arrayでも数値の配列なら何でもよい
ベクトルの和
const x = vec3.clone([1, 2, 3]); const y = vec3.clone([4, 5, 6]); const z = vec3.create(); // 変数を定義しておく必要がある vec3.add(z, x, y); // z = x + y
ベクトルの差
const x = vec3.clone([1, 2, 3]); const y = vec3.clone([4, 5, 6]); const z = vec3.create(); // 変数を定義しておく必要がある vec3.subtract(z, x, y); // z = x - y
ベクトルのスカラー倍
const x = vec3.clone([1, 2, 3]); const y = vec3.create(); // 変数を定義しておく必要がある vec3.scale(y, x, 3); // y = 3x
ベクトルの内積
const x = vec3.clone([1, 2, 3]); const y = vec3.clone([4, 5, 6]); const z = vec3.dot(x, y); // z = dot(x, y) inner product
ベクトルの外積
const x = vec3.clone([1, 2, 3]); const y = vec3.clone([4, 5, 6]); const z = vec3.create(); // 変数を定義しておく必要がある vec3.cross(z, x, y); // z = cross(x, y) outer product
ベクトルと行列の積
const x = vec3.clone([1, 2, 3]); const A = mat4.clone([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 2, 3, 1]); const y = vec3.create(); // 変数を定義しておく必要がある vec3.transformMat4(y, x, A); // y = Ax
は3次元で、 は4x4で数学的に は計算できませんが、
ベクトルの第4成分に1を補って、演算後、xyz成分をwで割ることにより3次元ベクトルにしています。詳細はメソッドのソースを読んでください。
vec3.transformMat4の第二引数がベクトルであり、第三引数が行列であり、実際の計算の順番とは異なる(ソース見て確認しました)ので注意してください。
単位ベクトル化
const x = vec3.clone([1, 2, 3]); const y = vec.create(); // 変数を定義しておく必要がある vec3.normalize(y, x);
ベクトルの長さ
const x = vec3.clone([1, 2, 3]); const y = vec3.length(x)
ベクトルの長さの2乗はvec3.squaredLengthメソッドで計算できます。
ベクトルの距離
const x = vec3.clone([1, 2, 3]); const y = vec3.clone([4, 5, 6]); const z = vec3.distance(x, y)
ベクトルの距離の2乗はvec3.squaredDistanceメソッドで計算できます。
ベクトルの相等
const x = vec3.clone([1, 2, 3]); const y = vec3.clone([4, 5, 6]); const z = vec3.equals(x, y); // false
vec3.equalsメソッドは、各成分の差が glMatrix.EPSILON(=0.000001)以下の場合にtrueを返します。
厳密な相等を判定する場合、vec3.exactEqualsを使いましょう。
行列の定義
const A = mat4.create(); // 全成分 0 で初期化されます。
単位行列
const A = mat4.create();
mat4.identity(A);
行列を特定の値で初期化
const A = mat4.clone([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 2, 3, 1]); // 実引数はArray<number>でもFloat32Arrayでも数値の配列なら何でもよい
任意軸回りの回転(演算)
Aに右からX軸回りに45度回転する行列をかけた行列を取得する例
const A = mat4.clone([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 2, 3, 1]); const B = mat4.create(); // 変数を定義しておく必要がある mat4.rotate(B, A, 45 / 180 * Math.PI, [1, 0, 0]);
X,Y,Z軸回りのメソッドとして、mat4.rotateX,mat4.rotateY,mat4.rotateZがありますが、使う必要はないと思います。
平行移動(演算)
AにX軸方向に+4平行移動する行列をかけた行列を取得する例
const A = mat4.clone([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 2, 3, 1]); const B = mat4.create(); // 変数を定義しておく必要がある mat4.translate(B, A, [4, 0, 0]);
拡大縮小(演算)
AにX軸方向に+4倍、Y軸方向に+1倍、Z軸方向に+1倍、拡大縮小する行列をかけた行列を取得する例
const A = mat4.clone([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 2, 3, 1]); const B = mat4.create(); // 変数を定義しておく必要がある mat4.scale(B, A, [4, 1, 1]);
行列同士の掛け算
const A = mat4.clone([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 2, 3, 1]); const B = mat4.clone([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 4, 5, 6, 1]); const C = mat4.create(); // 変数を定義しておく必要がある mat4.multiply(C, A, B);
行列の積は非可換ですので、掛ける順番に注意しましょう。
逆行列
const A = mat4.clone([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 2, 3, 1]); const B = mat4.create(); // 変数を定義しておく必要がある mat4.invert(B, A);
視野変換
const A = mat4.create(); // 変数を定義しておく必要がある mat4.lookAt(A, left, right, bottom, top, near, far);
正射影
const A = mat4.create(); // 変数を定義しておく必要がある mat4.ortho(A, eye, center, up);
透視投影
const A = mat4.create(); // 変数を定義しておく必要がある mat4.frustum(A, left, right, bottom, top, near, far);
画角を指定した透視投影
const A = mat4.create(); // 変数を定義しておく必要がある mat4.perspective(A, fovy, aspect, near, far);