three.js r73 Google Chrome 46.0.2490.86 m |
■three.jsでバンプマッピング、キューブマッピング、屈折マッピング [ サンプルページの表示 ] | Prev Top Next | |
|
今回はバンプマッピング、キューブマッピング、屈折マッピングです。屈折マッピングはちょっと使えないです。
例によってTypeScript使ってますので PlayGround サイトでJavaScriptにコンパイルしてください。
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 ); } )(); }