この記事は先日投稿したこちらの記事の続きとなります。
はじめに
今回は前回までで表示したポリゴン単体を回転させたいと思います。
回転させるために必要なモノ
3Dオブジェクトを回転させるためには行列が必要になります。
なぜ行列が必要なのかはこちらのサイトなどを参考にしてもらうと何となく分かると思います。
なにはともあれ行列が必要なわけです。
行列
とはいえ行列が必要といわれてもどのように作ればいいのかわかりません。
ですので今回はglMatrixという行列生成ライブラリを利用しました。(あくまでも行列生成ライブラリなので生WebGL描画という当初の目的は継続中です。(断言))
れっつ回転
glMatrixを使用して回転させる方法について、今回はこちらの記事を参考にさせて頂きました。
頂点シェーダの変更
glmatrixを追加した上で頂点シェーダの変更をします。
今回の追加したコードに関してはコメントで簡易的に説明をしてあります。
hindex.tml
<script id="vs" type="x-shader/x-vertex">
// 平行起動回転行列
uniform mat4 modelviewMatrix;
// 錐台変換行列
uniform mat4 projectionMatrix;
// 頂点座標
attribute vec3 position;
// 頂点の法線ベクトル
attribute vec3 normal;
// 法線ベクトルと平行移動回転行列との積
varying vec3 e_normal;
attribute vec4 color;
varying lowp vec4 vColor;
void main ()
{
// 頂点座標をクリッピング座標系に変換
gl_Position = projectionMatrix * modelviewMatrix * vec4(position, 1.0);
// 法線ベクトルを世界座標系に変換
e_normal = vec3(modelviewMatrix * vec4(normal, 0.0));
vColor = color;
}
</script>
- varying
- 頂点シェーダからフラグメントシェーダに送るデータ
フラグメントシェーダの変更
index.html
<script id="fs" type="x-shader/x-fragment">
// 法線ベクトルと平行移動回転行列との積
precision mediump float;
varying vec3 e_normal;
varying lowp vec4 vColor;
void main ()
{
// 法線ベクトルを正規化
vec3 n = normalize(e_normal);
// 法線ベクトルと光ベクトルとの内積で光量を決定
float l = abs(dot(n, normalize(vec3(-1, 1, 1))));
gl_FragColor = vColor;
}
</script>
描画時に回転させる
script.js
var frame = 0;
function render()
{
frame++;
// 錐台行列の生成
var proj_mat = mat4.create();
mat4.frustum(proj_mat, -1, 1, -1, 1, 3, 10);
// 移動回転行列の生成
var mv_mat = mat4.create();
mat4.translate(mv_mat, mv_mat, [0, 0, -6]);
mat4.rotate(mv_mat, mv_mat, frame * 0.01, [0, 1, 0]);
// uniformでShaderに送信
gl.uniformMatrix4fv(gl.getUniformLocation(program, "projectionMatrix"), false, proj_mat);
gl.uniformMatrix4fv(gl.getUniformLocation(program, "modelviewMatrix"), false, mv_mat);
// ======== Start 5.背景描画 ========
...
// ======== End 8.描画する ========
// 一定時間ごと処理をループ
setTimeout(render, 16);
}
追記
3d感が薄かったためZ軸をズラしました。
script.js
// Z軸を0から0.5に変更
var position = [
0, 0.5, 0.5,
-0.5, -0.5, 0.5,
0.5 ,-0.5, 0.5
];
くるくる
おわりに
やっと動いてるものを描画することができました。
ポリゴン1枚を描画して回転させるだけですが、ここまで行うのにそこそこのコード量が必要でした。
生WebGLでの描画、回転などが行えましたので、次回はなにかライブラリを使用してさくっと3Dオブジェクトを表示させたいと思います。