1. 程式人生 > >THREE.js為正方體的6個面貼上圖片

THREE.js為正方體的6個面貼上圖片

效果圖

這裡寫圖片描述
這裡寫圖片描述

程式碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>three</title>
</head>
<body> <script src="../learning-threejs-master/libs/three.js"></script> <script src="../learning-threejs-master/libs/OrbitControls.js"></script> <script> //建立一個renderer , var renderer = new THREE.WebGLRenderer({antialias:true}); //設定清空顏色,每秒會渲染60次,渲染的時候會使用此顏色先清空
renderer.setClearColor( new THREE.Color(0xEEEEEE, 1.0) ); //設定渲染尺寸 renderer.setSize( window.innerWidth , window.innerHeight ); //設定陰影允許 renderer.shadowMapEnabled = true; //將webgl元素新增到body中 document.body.appendChild( renderer.domElement ); //建立場景 var scene = new THREE.Scene(); //建立一個透視相機,45是相機的視角 , 寬高比是螢幕的寬高比 , 最近能看到0.1 , 最遠能看到10000
var camera = new THREE.PerspectiveCamera(45 , window.innerWidth/window.innerHeight , 0.1 , 10000 ); //將相機放到x:1000 , y:1000 , z:1000的位置 camera.position.set( 1000 , 1000 , 1000 ); //設定相機的朝向,可以認為與相機鏡頭垂直的軸線應該和哪一個軸相交 camera.up.set( 0 , 1 , 0 ); //將相機的鏡頭對準x:0 , y:0 , z:0的位置 經過這個設定相機就被固定住了 camera.lookAt({x:0,y:0,z:0}); //將相機新增到場景中 scene.add( camera ); //建立一個自然光,自然光無處不在 var light1 = new THREE.AmbientLight(0xffffff); //設定燈光的位置 light1.position.set( 1000 , 1000 , 1000 ); //將燈光加入場景 scene.add( light1 ); //建立一個長寬高600的立方體 var geometry = new THREE.CubeGeometry( 600 , 600 , 600 ); //建立一個phone材質並且用圖片作為紋理 var material = new THREE.MeshPhongMaterial( { map: THREE.ImageUtils.loadTexture('./texture-atlas.jpg') } ); var bricks = [ new THREE.Vector2(0, .666) , new THREE.Vector2(.5, .666), new THREE.Vector2(.5, 1), new THREE.Vector2(0, 1) ]; var clouds = [ new THREE.Vector2(.5, .666), new THREE.Vector2(1, .666), new THREE.Vector2(1, 1), new THREE.Vector2(.5, 1) ]; var crate = [ new THREE.Vector2(0, .333), new THREE.Vector2(.5, .333), new THREE.Vector2(.5, .666), new THREE.Vector2(0, .666) ]; var stone = [ new THREE.Vector2(.5, .333), new THREE.Vector2(1, .333), new THREE.Vector2(1, .666), new THREE.Vector2(.5, .666) ]; var water = [ new THREE.Vector2(0, 0), new THREE.Vector2(.5, 0), new THREE.Vector2(.5, .333), new THREE.Vector2(0, .333) ]; var wood = [ new THREE.Vector2(.5, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, .333), new THREE.Vector2(.5, .333) ]; // 清除現有的UV對映,geometry物件的faceVertexUvs屬性包含該geometry各個面的座標對映。 geometry.faceVertexUvs[0] = []; // 立方體的每個面實際上是由2個三角形組成的。所以我們必須單獨對映每個三角形 // 個面的頂點座標的定義順序必須遵循逆時針方向。為了對映底部三角形,我們需要使用的頂點指數0,1和3, // 而要對映頂部三角形,我們需要使用索引1,2,和頂點的3。 geometry.faceVertexUvs[0][0] = [ bricks[0], bricks[1], bricks[3] ]; geometry.faceVertexUvs[0][1] = [ bricks[1], bricks[2], bricks[3] ]; geometry.faceVertexUvs[0][2] = [ clouds[0], clouds[1], clouds[3] ]; geometry.faceVertexUvs[0][3] = [ clouds[1], clouds[2], clouds[3] ]; geometry.faceVertexUvs[0][4] = [ crate[0], crate[1], crate[3] ]; geometry.faceVertexUvs[0][5] = [ crate[1], crate[2], crate[3] ]; geometry.faceVertexUvs[0][6] = [ stone[0], stone[1], stone[3] ]; geometry.faceVertexUvs[0][7] = [ stone[1], stone[2], stone[3] ]; geometry.faceVertexUvs[0][8] = [ water[0], water[1], water[3] ]; geometry.faceVertexUvs[0][9] = [ water[1], water[2], water[3] ]; geometry.faceVertexUvs[0][10] = [ wood[0], wood[1], wood[3] ]; geometry.faceVertexUvs[0][11] = [ wood[1], wood[2], wood[3] ]; mesh = new THREE.Mesh(geometry, material); scene.add( mesh ); var orbitCtl = new THREE.OrbitControls( camera ); orbitCtl.autoRotate = false ; var clock = new THREE.Clock(); function threeStart(){ var delta = clock.getDelta(); orbitCtl.update( delta ); renderer.clear(); renderer.render( scene , camera ); requestAnimationFrame( threeStart ); }; threeStart();
</script> </body> </html>

註釋

這裡寫圖片描述

//此程式碼所描述的就是上圖中坐上角的那個圖,座標系的原點是左下角,(0 , 0.666)表示的是x軸是0y軸是距離原點2/3的地方
//(0.5 , 0.666)表示x軸是0.5 y軸是距離原點2/3的地方,也就是上圖中左上那個圖的右下方那個點,紋理座標是逆時針
var bricks = [
  new THREE.Vector2(0, .666),
  new THREE.Vector2(.5, .666),
  new THREE.Vector2(.5, 1),
  new THREE.Vector2(0, 1)
];

geometry物件的faceVertexUvs屬性包含該geometry各個面的座標對映。既然我們對映到一個多維資料集,你可能會疑惑為什麼陣列中有12個面。原因是在ThreeJS模型中,立方體的每個面實際上是由2個三角形組成的。所以我們必須單獨對映每個三角形。上述場景中,ThreeJS將為我們載入單一材料貼圖,自動分拆成三角形並對映到每個面。

這裡要注意每個面的頂點座標的定義順序必須遵循逆時針方向。為了對映底部三角形,我們需要使用的頂點指數0,1和3,而要對映頂部三角形,我們需要使用索引1,2,和頂點的3。
這裡寫圖片描述

geometry.faceVertexUvs[0] = [];  //清除現有的UV對映

//重新設定UV對映
geometry.faceVertexUvs[0][0] = [ bricks[0], bricks[1], bricks[3] ];
geometry.faceVertexUvs[0][1] = [ bricks[1], bricks[2], bricks[3] ];

geometry.faceVertexUvs[0][2] = [ clouds[0], clouds[1], clouds[3] ];
geometry.faceVertexUvs[0][3] = [ clouds[1], clouds[2], clouds[3] ];

geometry.faceVertexUvs[0][4] = [ crate[0], crate[1], crate[3] ];
geometry.faceVertexUvs[0][5] = [ crate[1], crate[2], crate[3] ];

geometry.faceVertexUvs[0][6] = [ stone[0], stone[1], stone[3] ];
geometry.faceVertexUvs[0][7] = [ stone[1], stone[2], stone[3] ];

geometry.faceVertexUvs[0][8] = [ water[0], water[1], water[3] ];
geometry.faceVertexUvs[0][9] = [ water[1], water[2], water[3] ];

geometry.faceVertexUvs[0][10] = [ wood[0], wood[1], wood[3] ];
geometry.faceVertexUvs[0][11] = [ wood[1], wood[2], wood[3] ];