2016年8月28日日曜日

Three.jsでマテリアルを動かす

Three.js(r79)でオブジェクトのマテリアルを動かしてみる。具体的には、平面オブジェクトのマテリアルとして画像を読み込み、その画像を左方向に移動させる。

以下のようにマテリアルを変化させる。


 ↓↓↓



以下は、THREE.ShaderMaterialとプログラマブルシェーダであるGLSLでマテリアルを移動させる手順。


1.GLSLのコーディング(頂点シェーダ)


今回は頂点シェーダを変更する必要はないが、この場合でも頂点シェーダーの記述は必要。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script id="vshader" type="x-shader/x-vertex">
// フラグメントシェーダーへ渡す変数
varying vec2 vUv;
 
void main() {
 // uv: UV座標(組み込み変数)
 vUv = uv;
 
 // 頂点位置(position)をモデル行列(modelViewMatrix)でワールド座標に変換
 vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
 
 // ビュー行列(projectionMatrix)でスクリーン座標に変換
 gl_Position = projectionMatrix * mvPosition;
}
</script>

※座標変換をしているだけで、頂点位置が変化しているわけではない。

2.GLSLのコーディング(フラグメントシェーダ)


フラグメントシェーダで画像が左に移動する動きを記述する。画像のどの位置の色情報を参照するかUV座標で指定するが、そのUV座標を左にずらしていくことで、画像を左に移動させる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<script id="fshader" type="x-shader/x-fragment">
  // テクスチャ
 uniform sampler2D texture;
  // どのくらい画像をずらすか
  // THREE.ShaderMaterialで設定したuniform変数
 uniform float delta;
 
 // 頂点シェーダーからわたされた変数(UV座標)
 // UV座標は-1~1に正規化されている
 varying vec2 vUv;
 
 void main() {
  vec3 color = vec3(0.0, 0.0, 0.0);
  // 1024は画像の横サイズ
  float x = vUv.x + delta/1024.0;
 
  if( x > 1.0 ) {
   color = texture2D( texture, vec2( x - 1.0, vUv.y) ).xyz;
  } else {
   color = texture2D( texture, vec2( x, vUv.y ) ).xyz;
  }
  // 描画色を設定
  gl_FragColor = vec4(color, 1.0);
  }
</script>


3.オブジェクトの作成


GLSLを利用するためにTHREE.ShaderMaterialでマテリアルを作成する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// ジオメトリの作成
var geometry = new THREE.PlaneGeometry( 4, 3);
 
// テクスチャの作成
var texture = new THREE.TextureLoader().load( '../image/persimmon.jpg' );
 
// マテリアルの作成
// uniforms: シェーダーに渡す変数を指定
// vertexShader: 頂点シェーダーを指定
// fragmentShader: フラグメントシェーダーを指定
var material = new THREE.ShaderMaterial( {
  uniforms: {
   delta: { type: 'f', value: 0.0 },
   texture:   { type: 't', value: texture }
  },
  vertexShader:   document.getElementById( 'vshader' ).textContent,
  fragmentShader: document.getElementById( 'fshader' ).textContent
 });
 
// オブジェクトの作成
var plane = new THREE.Mesh( geometry, material );

4.マテリアルを移動させる


setIntervalでマテリアルの移動速度を調整。

1
2
3
4
5
6
7
8
// 画像の横サイズ
var imgWidth = 1024;
setInterval( function(){
 if( plane.material.uniforms.delta.value > imgWidth ) {
  plane.material.uniforms.delta.value = 0.0;
 }
 plane.material.uniforms.delta.value += 1.0;
}, 100 );

後は、シーンやカメラなど、通常Three.jsで必要なものを追加するだけ。



0 件のコメント:

コメントを投稿