立方体の各面にテクスチャを貼る - three.js アプリ
HelloWorld(https://threejs.org/docs/index.html#manual/introduction/Creating-a-scene)の次からいきなり詰んだので記事書きました .
環境
- 0.95.0 from npm
dom操作が苦手なので必要以上にjqueryが登場しますが,その場合はv3とします.
material
次のコードは https://threejs.org/docs/index.html#manual/introduction/Creating-a-scene と殆ど変わらない.
textureの情報を持つmaterialを作って適用することで,textureが貼られた立方体が生成される.
なので,コメントで区切られた部分を書き換える.
const screenWidth = 800; const screenHeight = 600; let scene; let camera; let renderer; $(()=>{ scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera( 75, screenWidth/screenHeight, 0.1, 1000 ); renderer = new THREE.WebGLRenderer(); renderer.setSize( screenWidth, screenHeight ); $("#wrapper").append($(renderer.domElement)); let geometry = new THREE.BoxGeometry(10, 10, 10); // ====================================== let material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); // ====================================== let cube = new THREE.Mesh( geometry, material ); scene.add( cube ); camera.position.set(0,0,15); let animate = () => { requestAnimationFrame( animate ); cube.rotation.x += 0.01; cube.rotation.y += 0.015; renderer.render( scene, camera ); }; animate(); });
各面に同じテクスチャを貼る
texture を読み込むために TextureLoader
を使う.callbackが指定できるので,非同期かな?.
https://threejs.org/docs/index.html#api/loaders/TextureLoader
material の生成は,無地と同様に MeshBasicMaterial
が使える.
https://threejs.org/docs/index.html#api/materials/MeshBasicMaterial
次の例では,./a/sai1.png
を読み込んで,6面に表示させている.(1面に1枚の画像)
let loader = new THREE.TextureLoader(); let texture = loader.load( 'a/sai1.png' ); let material = new THREE.MeshBasicMaterial( { map: texture } );
6面に異なるテクスチャを貼る
6つmaterialを生成して,配列で纏めれば良い.
let loader = new THREE.TextureLoader(); let material = [ new THREE.MeshBasicMaterial({map: loader.load( 'a/sai2.png' )}), new THREE.MeshBasicMaterial({map: loader.load( 'a/sai5.png' )}), new THREE.MeshBasicMaterial({map: loader.load( 'a/sai3.png' )}), new THREE.MeshBasicMaterial({map: loader.load( 'a/sai4.png' )}), new THREE.MeshBasicMaterial({map: loader.load( 'a/sai1.png' )}), new THREE.MeshBasicMaterial({map: loader.load( 'a/sai6.png' )}) ];
1枚の画像で出来ないのか?
MeshStandardMaterial
とか,UV指定してやれば出来るんじゃないのーと思っていましたが,(画像すら)うまく表示させることが出来ず.
壁紙を指定するサンプルコードも6枚指定しているので,この実装がthree.jsにとってスタンダードかもしれません.
new THREE.CubeTextureLoader() .setPath('a/') .load(['bg.gif', 'bg.gif', 'bg.gif', 'bg.gif', 'bg.gif', 'bg.gif'], (textureCube) => { scene.background = textureCube; });