stats.js」タグアーカイブ

Three.jsにて自作シェーダーを試す際のサンプル Part.2

前回の続き。
GUIにてパラメータの調整ができると楽なので、今回はdat.guiによるパラメータの調整と、stats.jsによるリソースの状態の確認について書く。
サンプルは以下のURLを参照。
http://nktk-tech.com/example/three-template2/main.html

解説

dat.guiは以下のように用いる。

dat.gui周りの処理抜粋// dat.guiにて操作したいパラメータを持つオブジェクト
const lightProperty = {
    "color" : "#ffffff",
    "pos_x" : 3.0,
    "pos_y" : 4.0,
    "pos_z" : 0.0
};

// dat.guiの項目を初期化
const gui = new dat.GUI({name: 'light_property'});
gui.addColor(lightProperty, 'color').onChange( () => light.color.set(lightProperty.color) );
gui.add(lightProperty, 'pos_x', -5.0, 5.0, 0.1).onChange( 
    () => light.position.setX(lightProperty.pos_x ));
gui.add(lightProperty, 'pos_y', -5.0, 5.0, 0.1).onChange( 
    () => light.position.setY(lightProperty.pos_y ))
gui.add(lightProperty, 'pos_z', -5.0, 5.0, 0.1).onChange( 
    () => light.position.setZ(lightProperty.pos_z ));

まず、dat.guiにて変更したいパラメータを持つオブジェクトを用意する。
色に関してはThree.jsもdat.guiもCSSの書き方に対応しているのでそれで初期化すると楽かも。
そしてdat.guiのクラスに対して、パラメータのオブジェクトを登録していくと、パラメータをGUIで操作できるようになる。

色については、dat.GUI.addColor, それ以外は dat.GUI.addにて項目を追加できる。
第一引数にパラメータのオブジェクト 、第二引数は操作したいパラメータを文字列を指定する。
パラメータが数値の場合は、第三引数以降に最小値、最大値、刻み幅を指定できる。
詳しくは下記の公式ドキュメントを参照。
https://github.com/dataarts/dat.gui/blob/master/API.md#GUI+add

追加したパラメータの型によってdat.guiがよしなにgui作成してくれる。
詳しくは下記チュートリアル参照。これ見とけば大体のこと解決できる気がする。
http://workshop.chromeexperiments.com/examples/gui

.addにてdat.guiの項目を追加すると、dat.guiのControllerクラスが返される。
https://github.com/dataarts/dat.gui/blob/master/API.md#Controller
これの.onChangeにて、値が変化したときのコールバック関数を設定できる。
アニメーションループ内でフレームごとにプロパティ再設定するなら、.onChangeに関数設定する必要ないかも。

前回の記事のにそのままdat.guiを加えると、dat.guiの操作と同時に表示している3Dオブジェクトが動いちゃうので注意する。
OrbitControlsの第二引数に、表示用のcanvasのdomを渡してやれば、canvas範囲外でのマウスドラッグは無視できるようになる。

OrbitControlsの設定例const controls = new THREE.OrbitControls( camera, document.querySelector('#myCanvas') );

stats.jsによるfpsの表示は以下のコードで可能。

stats.js周りの処理を抜粋// stats.jsによりfpsを表示
const stats = new Stats();
stats.dom.style.left = "10px";
stats.dom.style.top = "10px";
document.body.appendChild( stats.dom );

// 毎フレーム時に実行されるループイベント
function tick() {
    controls.update();
    renderer.render(scene, camera);
    stats.update(); // 毎フレームごとにstats.update()を呼ぶ必要がある。
    requestAnimationFrame(tick);
}

クラスを作成して、適当なdomの配下に加えて、毎フレームupdateを呼び出すだけなので簡単。
他のリソースを表示する拡張なんかもあるみたい。
参考 : https://qiita.com/dockurage/items/13b71f86c7ac92dfb4c

最終的に、全体のコードは以下のようになった。

続きを読む