FLINTERS Engineer's Blog

FLINTERSのエンジニアによる技術ブログ

texgen.jsことはじめ + 生成したテクスチャをthree.jsで使う

こんにちは@joytomoです。
先日FITC Tokyo 2015にて、three.jsの作者として知られるMr.doobことリカルド・カベッロ氏の講演を聞いてきました。
そこで新作jsライブラリtexgen.jsが紹介されており、面白そうなので触ってみました。

texgen.jsはその名の通りテクスチャをジェネレートするjsライブラリで、画像データを用いずに軽量かつ複雑なテクスチャを生成することができます。

生成したテクスチャをthree.jsの3Dオブジェクトに貼付ける方法も紹介します。


サンプルを試してみる

Mr.doob氏のgithubからcloneしてきましょう。

$git clone https://github.com/FukurouLabo/circuit-app-search.git

まずtexgen.js/example/index.htmlをブラウザで開いてみます。
下記のような画面が表示されますね。
スクリーンショット 2015-03-01 23.29.00.png
なんとこれらは、全く画像ファイルを使わずtexgen.jsで生成しているようです。

続いてtexgen.js/editor/index.htmlを開いてみましょう。
スクリーンショット 2015-03-01 23.16.21.png
なにかのUIのようですね。
試みに左のボタンを適当に触っていくと、右の画面に2Dと3Dでグラフィックが表示されます。
スクリーンショット 2015-03-01 23.16.48.png
これはテクスチャのエディタのようでした。
しかも右下に表示されるソースコードをコピペすれば、表示されているテクスチャがそのまま使えるようです。便利ですね!

生成したテクスチャを表示させてみる

スクリーンショット 2015-03-01 23.15.53.png
試しに上のようなオリジナルテクスチャを作ってみました。
右下のコードをコピペすればそのまま使えるはずです。
先程のtexgen.js/example/index.htmlを参考に書いていきます。

<!DOCTYPE html>
<html lang="en">
<head><title>texgen.js</title></head>
<body>
<script src="../src/TexGen.js"></script>
<script>
  //script内はエディタのコピペです
  var texture = new TG.Texture( 256, 256 )
                .add( new TG.Checkerboard().size( 8, 64 ).offset( 0, 0 ).rowShift( 0 ) )
            .add( new TG.SinX().frequency( 0.16 ).offset( 0 ) )
            .add( new TG.Noise() )
            .add( new TG.Pixelate().size( 1, 1 ) )
                .toCanvas();
</script></body></html>

早速開いてみます。
スクリーンショット 2015-03-01 23.19.55.png

なんかエラーが出ました。
サンプルコードと比較してみたところ、ここが変ですね。

.add( new TG.Checkerboard().size( 8, 64 ).offset( 0, 0 ).rowShift( 0 ) )

CheckerboardではなくCheckerBoardが正しいです。

.add( new TG.CheckerBoard().size( 8, 64 ).offset( 0, 0 ).rowShift( 0 ) )

ここを直したら動きました。
エディタで表示されたコードをコピペしただけなので、エディタのバグが残っていたようでした。
スクリーンショット 2015-03-01 23.20.58.png

ついでにテクスチャの要素にtintというパラメータを追加すると、色が付けられるようでした。

.add( new TG.SinX().frequency( 0.16 ).offset( 0 ).tint( 0.5, 0, 0 ) )

スクリーンショット 2015-03-01 23.20.16.png

three.jsでテクスチャを使ってみる

texgen.jsで生成したテクスチャをthree.jsの3Dオブジェクトに貼付けてみましょう。
テクスチャをcanvas要素に貼付けてthree.jsから参照することで出来ます。
これはtexgenというよりthree.js側でcanvas要素を取得するのが結構ややこしいのですが、本稿はtexgenの紹介なのでthree周りは割愛します。

<!DOCTYPE html>
<html lang="en">
<head><title>texgen.js</title></head>
<body>
<canvas id= "texture"></canvas>
<script src="../src/TexGen.js"></script>
<script src="../editor/ext/three.min.js"></script>
<script>
  var texture = new TG.Texture( 256, 256 )
                .add( new TG.CheckerBoard().size( 8, 64 ).offset( 0, 0 ).rowShift( 0 ) )
            .add( new TG.SinX().frequency( 0.16 ).offset( 0 ).tint( 0.5, 0, 0 ) )
            .add( new TG.Noise() )
            .add( new TG.Pixelate().size( 1, 1 ) )

  var canvas = document.getElementById('texture');
  canvas.width = 256;
  canvas.height = 256;
  ctx = canvas.getContext('2d'); 
  ctx.putImageData( texture.toImageData( ctx ), 0, 0 );

  var scene = new THREE.Scene();</p>

  var geometry = new THREE.BoxGeometry(10,10,10);
  var material = new THREE.MeshBasicMaterial({ 
                     color: 0xffffff,
             transparent: true,
                     map: new THREE.Texture( document.getElementById("texture"))
                 });
  var cube = new THREE.Mesh(geometry, material);
  cube.material.map.needsUpdate = true;
  scene.add(cube);

  var camera = new THREE.PerspectiveCamera(45, 1, 1, 1000 );
  camera.position.set(0, 10, 20);
  camera.lookAt(cube.position);

  var renderer = new THREE.WebGLRenderer();
  renderer.setSize(256, 256);
  renderer.setClearColor(0xffffff, 1);
  document.body.appendChild(renderer.domElement);

   function render(){
    requestAnimationFrame(render);
    cube.rotation.y += Math.PI / 100;
    renderer.render(scene, camera);
  }
  render();

<p></script></body></html>

ちゃんと表示されました。
スクリーンショット 2015-03-02 2.23.06.png

終わりに

FITCではtexgen.jsの他にframe.jsというライブラリも紹介されてました。なんとthree.jsの3Dアニメーションエディタとのこと!
ということでこちらも触ってみたのですが、まだ開発中らしく動かし方がよく分からない・・・
しかしこれは今後も要チェックです。

近々出るであろうUnity5もWebGL対応ということで、2015年後半はWebGL界隈が今まで以上に熱くなってきそうですね!

ではまた。

(元記事:texgen.jsことはじめ + 生成したテクスチャをthree.jsで使う