LoginSignup
1
1

More than 5 years have passed since last update.

WebGL学習記録(5) 複数のモデル、再帰処理でアニメーション

Posted at

参考webglorg;
原則として上記ページを見ながら学習した記録です。
Screen Shot 2015-10-29 at 16.04.35.png

複数モデルのレンダリング

頂点バッファの再利用

VBOを再利用し、座標変換行列を操作して複数モデルの描写を表現する。

座標変換行列の再利用

座標変換行列も再利用します。
実際、複数モデルを違う位置にレンダリングするとき、操作するのはモデル変換行列のみ。

手順としては

  • ビュー・プロジェクションのりょう左表変換行列を用意
  • あらかじめ二つは掛け合わせておく(pv)
  • 一つのモデル座標変換行列を用意(m1)
  • m1にpvを掛け合わせて uniform に登録
  • 一つ目のモデルを描写
  • 二つ目のモデル座標変換行列を用意(m2)
  • m2 に pv を掛け合わせて uniform 登録
  • 二つ目のモデルを描写
  • コンテキストのリフレッシュをして再描写

つまりどうなるか

一部抜粋。

// 各種行列の生成と初期化
var mMatrix = m.identity(m.create());
var vMatrix = m.identity(m.create());
var pMatrix = m.identity(m.create());
var tmpMatrix = m.identity(m.create());
var mvpMatrix = m.identity(m.create());

// ビュー×プロジェクション座標変換行列
m.lookAt([0.0, 0.0, 3.0], [0, 0, 0], [0, 1, 0], vMatrix);
m.perspective(90, c.width / c.height, 0.1, 100, pMatrix);
m.multiply(pMatrix, vMatrix, tmpMatrix);

// 一つ目のモデルを移動するためのモデル座標変換行列
m.translate(mMatrix, [1.5, 0.0, 0.0], mMatrix);

// モデル×ビュー×プロジェクション(一つ目のモデル)
m.multiply(tmpMatrix, mMatrix, mvpMatrix);

// uniformLocationへ座標変換行列を登録し描画する(一つ目のモデル)
gl.uniformMatrix4fv(uniLocation, false, mvpMatrix);
gl.drawArrays(gl.TRIANGLES, 0, 3);

// 二つ目のモデルを移動するためのモデル座標変換行列
m.identity(mMatrix);
m.translate(mMatrix, [-1.5, 0.0, 0.0], mMatrix);

// モデル×ビュー×プロジェクション(二つ目のモデル)
m.multiply(tmpMatrix, mMatrix, mvpMatrix);

// uniformLocationへ座標変換行列を登録し描画する(二つ目のモデル)
gl.uniformMatrix4fv(uniLocation, false, mvpMatrix);
gl.drawArrays(gl.TRIANGLES, 0, 3);

// コンテキストの再描画
gl.flush();

再帰処理と移動・回転・拡大縮小

今回は合計3つのポリゴンを描写する。
VBOや一部の座標変換行列を使い回すことによって、少ないリソースで大量のモデルを描写することが可能。

恒常ループ処理を実装する

変化の過程を常に更新し続ける、つまりアニメーションを実装する。
基本は setTimeout メソッドを使うことにする。
setTimeout メソッドは、第一引数に呼び出すことになる関数(処理)を、第二引数に関数を呼び出す経過時間をミリ秒で指定。

arguments クラスと callee プロパティ

arguments クラスの callee プロパティを参照することで、関数自身への山椒を得ることが可能。

再帰関数の中に詰め込む処理を選別

  • 画面のクリア
  • モデル座標変換行列の生成
  • uniform への座標変換行列の登録
  • 描写命令
  • 画面の更新
  • setTimeout + arguments.callee

つまりこうなる。

// minMatrix.js を用いた行列関連処理
// matIVオブジェクトを生成
var m = new matIV();

// 各種行列の生成と初期化
var mMatrix = m.identity(m.create());
var vMatrix = m.identity(m.create());
var pMatrix = m.identity(m.create());
var tmpMatrix = m.identity(m.create());
var mvpMatrix = m.identity(m.create());

// ビュー×プロジェクション座標変換行列
m.lookAt([0.0, 0.0, 5.0], [0, 0, 0], [0, 1, 0], vMatrix);
m.perspective(45, c.width / c.height, 0.1, 100, pMatrix);
m.multiply(pMatrix, vMatrix, tmpMatrix);

// カウンタの宣言
var count = 0;

// 恒常ループ
(function(){
    // canvasを初期化
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.clearDepth(1.0);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    // カウンタをインクリメントする
    count++;

    // カウンタを元にラジアンを算出
    var rad = (count % 360) * Math.PI / 180;

    // モデル1は円の軌道を描き移動する
    var x = Math.cos(rad);
    var y = Math.sin(rad);
    m.identity(mMatrix);
    m.translate(mMatrix, [x, y + 1.0, 0.0], mMatrix);

    // モデル1の座標変換行列を完成させレンダリングする
    m.multiply(tmpMatrix, mMatrix, mvpMatrix);
    gl.uniformMatrix4fv(uniLocation, false, mvpMatrix);
    gl.drawArrays(gl.TRIANGLES, 0, 3);

    // モデル2はY軸を中心に回転する
    m.identity(mMatrix);
    m.translate(mMatrix, [1.0, -1.0, 0.0], mMatrix);
    m.rotate(mMatrix, rad, [0, 1, 0], mMatrix);

    // モデル2の座標変換行列を完成させレンダリングする
    m.multiply(tmpMatrix, mMatrix, mvpMatrix);
    gl.uniformMatrix4fv(uniLocation, false, mvpMatrix);
    gl.drawArrays(gl.TRIANGLES, 0, 3);

    // モデル3は拡大縮小する
    var s = Math.sin(rad) + 1.0;
    m.identity(mMatrix);
    m.translate(mMatrix, [-1.0, -1.0, 0.0], mMatrix);
    m.scale(mMatrix, [s, s, 0.0], mMatrix)

    // モデル3の座標変換行列を完成させレンダリングする
    m.multiply(tmpMatrix, mMatrix, mvpMatrix);
    gl.uniformMatrix4fv(uniLocation, false, mvpMatrix);
    gl.drawArrays(gl.TRIANGLES, 0, 3);

    // コンテキストの再描画
    gl.flush();

    // ループのために再帰呼び出し
    setTimeout(arguments.callee, 1000 / 30);
})();

Screen Shot 2015-10-29 at 19.41.04.png

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1