three.js r73
 Google Chrome 46.0.2490.86 m

■three.jsでバンプマッピング、キューブマッピング、屈折マッピング [ サンプルページの表示 ] Prev Top Next
関連ページ:

今回はバンプマッピング、キューブマッピング、屈折マッピングです。屈折マッピングはちょっと使えないです。

例によってTypeScript使ってますので PlayGround サイトでJavaScriptにコンパイルしてください。


---javascript.ts---  ↑
class myThree
{
   private renderer = null;
   private camera = null;
   private mesh = [];
   private rotation = new THREE.Vector3( 0, 0, 0 );
   private scene = null;
   
   private _width: number = 600;
   private _height: number = 400;
   
   public get width(){ return this._width }
   public set width( value:number )
   {
      this.dispose();
      this._width = value;
      var textureIndex:number = document.getElementById( "Texture" ).selectedIndex;
      mythree.changeScene( 1, textureIndex );
   }
   
   public get height(){ return this._height }
   public set height( value:number )
   {
      this.dispose();
      this._height = value;
      var textureIndex:number = document.getElementById( "Texture" ).selectedIndex;
      mythree.changeScene( 1, textureIndex );
   }

   // レンダラ―作成
   private createRenderer()
   {
      var renderer = new THREE.WebGLRenderer();
      renderer.setSize( this.width, this.height );
      renderer.setClearColor(0xf0f0ff);
      
      return renderer;
   }

   // カメラ作成
   private createCamera()
   {
      const fov:number = 60;
      const aspect:number = this.width / this.height;
      const znear:number = 1.0;
      const zfar:number = 1000.0;
      var camera = new THREE.PerspectiveCamera( fov, aspect, znear, zfar );
      // カメラ視点
      camera.position.set( 0.0, 0.0, 50.0 );
      // カメラの注視点
      camera.lookAt( new THREE.Vector3( 0, 0, 0 ) );
      
      return camera;
   }

   // テクスチャー作成
   private createTexture( path: string )
   {
      var loader = new THREE.TextureLoader();
      var texture = loader.load( path );

      // テクスチャーフィルター
      texture.minFilter = THREE.LinearMipMapLinearFilter;
      texture.magFilter = THREE.LinearMipMapLinearFilter;

      // 異方性フィルタリング
      texture.anisotropy = 16;
      
      return texture;
   }

   // キューブマップ作成
   private createCubeTexture( paths: string[], mapping: number = null )
   {
      var loader = new THREE.CubeTextureLoader();
      var texture = loader.load( paths );

      if( mapping != null )
      {
         texture.mapping = mapping;
      }
      
      // テクスチャーフィルター
      texture.minFilter = THREE.LinearMipMapLinearFilter;
      texture.magFilter = THREE.LinearMipMapLinearFilter;

      // 異方性フィルタリング
      texture.anisotropy = 16;
      
      return texture;
   }
   
   // シーン作成
   private createScene()
   {
      var scene = new THREE.Scene();
      return scene;
   }

   // ライト作成
   private createLight( lightIndex: number)
   {
      switch( lightIndex )
      {
         // 環境光
         // http://threejs.org/docs/#Reference/Lights/AmbientLight
         case 0:
            // 環境光の色
            var ambientLight = new THREE.AmbientLight( 0x505050 );
            return ambientLight;
            break;
            
         // 平行光源
         // http://threejs.org/docs/#Reference/Lights/DirectionalLight
         case 1:
            // 平行光源の色、強度
            var directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );
            // 光源から原点に向かう平行光源の方向ベクトル
            directionalLight.position.set( 1.0, 3.0, 2.0);
            return directionalLight;
            break;
      
         // 点光源
         // http://threejs.org/docs/#Reference/Lights/PointLight
         case 2:
            // 点光源の色、強度、減衰率( 0で減衰なし )
            var pointLight = new THREE.PointLight( 0xffffff, 1, 0 );
            // 点光源の座標
            pointLight.position.set(10.0, 10.0, 10.0);
            return pointLight;
            break;

         // 半球ライト
         // http://threejs.org/docs/#Reference/Lights/HemisphereLight
         case 3:
            // 空の色、地面の色、強度
            var hemisphereLight = new THREE.HemisphereLight( 0xa0a0ff, 0xa0ffa0, 1 );
            return hemisphereLight;
            break;

         // スポットライト
         // http://threejs.org/docs/#Reference/Lights/SpotLight
         case 4:
            // 色、強度、光が届く距離、光の範囲( 最大値:Math.PI/2 )、減衰率、光が暗くなる量
            var spotLight = new THREE.SpotLight(0xffffff, 1, 40, Math.PI / 3, 2, 0.5);
            // ライトの視点
            spotLight.position.set(5.0, 10.0, 0.0);
            // ライトの注視点
            spotLight.lookAt( new THREE.Vector3( 0, 0, 0 ) );            
            return spotLight;
            break;

         default:
            alert( "無効なライトです" );
            break;
      }
      
      return null;
   }
   
   // シーン変更
   public changeScene( lightIndex:number, textureIndex: number )
   {
      if( this.renderer == null )
      {
         this.renderer = this.createRenderer();
         document.body.appendChild( this.renderer.domElement );
      }

      if( this.camera == null )
      {
         this.camera = this.createCamera();
      }
      
      this.scene = this.createScene();

      var light = this.createLight(lightIndex);
      this.scene.add(light);
      
      // デカールマップ
      var texture = this.createTexture( 'Contents/moon.png' );
      
      // ハイトマップ
      var heightmap = this.createTexture( 'Contents/heightmap.png' );

      var cubeFiles = [];
      for( var i=0; i<6; i++ )
      {
         // 画像の順序は左、右、上、下、奥、手前
         cubeFiles[i] = 'Contents/bluecloud' + i.toString(10) +  '.jpg';
      }

      // キューブマップ
      var cubemap = this.createCubeTexture( cubeFiles );

      // 屈折マップ
      var refmap = this.createCubeTexture( cubeFiles, THREE.CubeRefractionMapping );
      
      var geometry = new THREE.SphereGeometry(24, 16, 16);
      
      var material = null;
      switch( textureIndex )
      {
         // 通常のテクスチャー
         case 0:
            material = new THREE.MeshPhongMaterial({ color: 0xffffff,
                                                     map: texture
                                                   });
           break;

         // バンプマッピング
         case 1:
            material = new THREE.MeshPhongMaterial({ color: 0xffffff,
                                                     specular: 0xcccccc,  // ハイライトの色
                                                     shininess:50,        // ハイライトの範囲
                                                     map: texture, 
                                                     bumpMap:heightmap,
                                                     bumpScale: 0.2       // バンプマッピングの高さ
                                                    });
           break;
         
         // キューブマッピング
         case 2:
            material = new THREE.MeshPhongMaterial({ color: 0xffffff,
                                                     specular: 0xcccccc,  // ハイライトの色
                                                     shininess:50,        // ハイライトの範囲
                                                     envMap: cubemap
                                                    });
           break;
         
         // 屈折マッピング
         // フレームバッファを屈折するのではなく、あくまでメッシュに貼り付けるキューブテクスチャーを屈折させるだけ。
         // 屈折のため裏側の画像が手前に表示される。
         case 3:
            material = new THREE.MeshPhongMaterial({ color: 0xffffff,
                                                     specular: 0xcccccc,   // ハイライトの色
                                                     shininess:50,         // ハイライトの範囲
                                                     envMap: refmap,
                                                     reflectivity: 1.0,    // 屈折マップの色強度
                                                     refractionRatio: 0.5  // 屈折率
                                                    });
           break;           
      }
      this.mesh[0] = new THREE.Mesh(geometry, material);
      this.scene.add(this.mesh[0]);
   }

   // メッシュのアニメーション
   public animationMesh( x:number, y:number, z:number )
   {
      if( this.mesh != null )
      {   
         this.rotation.x += x;
         this.rotation.y += y;
         this.rotation.z += z;

         for( var i=0; i<this.mesh.length; i++ )
         {
            this.mesh[i].rotation.set( this.rotation.x, this.rotation.y, this.rotation.z );
            this.mesh[i].scale.set( 1.0, 1.0, 1.0 );
         }
      }
   }

   // レンダリング
   public render()
   {
      if( this.renderer != null )
      {
         this.renderer.render( this.scene, this.camera );      
      }
   }
   
   public dispose()
   {
      if( this.renderer != null )
      {
         var element = document.getElementsByTagName("canvas");
         if( element.length == 1 )
         {
            document.body.removeChild(element[0]);
         }
         this.renderer.dispose();
         this.renderer = null;
      }
      this.camera = null;
   }
}

class FPS
{
   private dispFrame: number = 0;
   private frame: number = 0;
   private timer: Date = new Date();
   
   public getFPS()
   {
      var now = new Date();
      
      // 1秒経過してない
      if( now.getTime() - this.timer.getTime() < 1000 )
      {
         this.frame++;
      }
      else
      {
         this.timer = now;
         this.dispFrame = this.frame;
         this.frame = 0;
      }
      
      return this.dispFrame;
   }
}

var mythree = new myThree();
var fps = new FPS();

// シーンの初期化
function initialize()
{
   if( mythree != null )
   {
      var textureIndex:number = document.getElementById( "Texture" ).selectedIndex;
      mythree.changeScene( 1, textureIndex );
   }
}

// メインループ
function main()
{
   ( function renderLoop ()
      {
         requestAnimationFrame( renderLoop );
         mythree.animationMesh( 0, 0.005, 0 );
         
         mythree.render();

         // FPS表示
         var frame = fps.getFPS();
         $("div.fps").html( "FPS:" + frame );         
      }
   )();
}

Prev Top Next
inserted by FC2 system