《為什么要學習Three.js》
Three.js是JavaScript編寫的WebGL第三方庫。提供了非常多的3D顯示功能。
Three.js對WebGL進行了封裝,省去了很多WebGL底層的代碼,使得編寫Web的3D程序十分方便。
現如今,WebAR和WebVR逐漸進入人們的視野。由于Web不需要下載程序的簡便性使得更多的人傾向于在Web頁面開發VR/AR應用(快速捕捉客戶)。因此,學習WebGL的開發使得一個VR/AR開發者更具有競爭力。
今天,我們將簡單的從幾個方面來講解Three.js,已達到快速入門的目的。
知識需求:
簡單的Web前端知識(HTML、CSS和JS)
簡單的OpenGL的知識(包括OpenGL ES和WebGL)
《一個簡單的Three.js頁面框架》
由于Three.js需要一個簡單的web服務器來測試,所以我們需要搭建一個簡單的HTTP服務器。
對于大多數人來說,搭建web服務器是一個十分簡單的事情,但對一些新手我們可以使用集成環境來快速搭建web服務器來測試(像是eclipse中集成的tomcat服務器一樣)。
在這里我推薦使用Web Storm軟件,搞前端開發的程序員對此軟件并不陌生,其擴展性高使用十分便捷。
下面我們開始搭建一個簡單的Three.js頁面的框架。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example 01.01 - Bacis skeleton</title>
<script type="text/javascript"
src="../libs/three.js"></script>
<script type="text/javascript"
src="../libs/jquery-3.1.1.js"></script>
<style>
body{
/*設置頁面的樣式*/
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<!—用于顯示WebGL輸出的div-->
<div id="WebGL-output">
</div>
<!—以下為Three.js的具體代碼-->
<script type="text/javascript">
//在加載過后自動運行的函數
$(function () {
//在此輸入Three.js代碼
});
</script>
</body>
</html>
《渲染并創建一個三維對象》
在上文的注釋 在此輸入Three.js代碼的地方刪除該注釋,輸入以下代碼。
運行測試一下,效果如圖。
后面我們將會講解這一段簡單的代碼。
$(function () {
var scene=new THREE.Scene();
var camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);
var renderer=new THREE.WebGLRenderer();
renderer.setClearColor(0xEEEEEE,0.5);
renderer.setSize(window.innerWidth,window.innerHeight);
var axes=new THREE.AxisHelper(20);
scene.add(axes);
var planeGeometry = new THREE.PlaneGeometry(60,20,1,1);
var planeMaterial = new THREE.MeshBasicMaterial({color:0xcccccc});
var plane=new THREE.Mesh(planeGeometry,planeMaterial);
plane.rotation.x=-0.5*Math.PI;
plane.position.x=15;plane.position.y=0;plane.position.z=0;
scene.add(plane);
var cubeGeometry = new THREE.CubeGeometry(4,4,4);
var cubeMaterial = new THREE.MeshBasicMaterial({color:0xff0000,wireframe:true});
var cube=new THREE.Mesh(cubeGeometry,cubeMaterial);
cube.position.x=-4;cube.position.y=3;cube.position.z=0;
scene.add(cube);
var sphereGeometry=new THREE.SphereGeometry(4,20,20);
var sphereMaterial=new THREE.MeshBasicMaterial({color:0x7777ff,wireframe:true});
var sphere=new THREE.Mesh(sphereGeometry,sphereMaterial);
sphere.position.x=20;sphere.position.y=4;sphere.position.z=2;
scene.add(sphere);
camera.position.x=-30;camera.position.y=40;camera.position.z=30;
camera.lookAt(scene.position);
$("#WebGL-output").append(renderer.domElement);
renderer.render(scene,camera);
});
var scene=new THREE.Scene();
var camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);
var renderer=new THREE.WebGLRenderer();
在本章的一開始,定義了scene、camera和renderer(場景、相機和渲染器)。
scene是一個容器,保存并跟蹤想要渲染的物體,在后面創建了幾何體之后(如立方體和球體等)會添加到scene變量中。
camera變量定義了在渲染好的scene里看到什么。
最后是renderer對象,renderer對象負責計算指定的相機角度下的瀏覽器中scene的呈現樣子。
在以上實例中,我們創建了一個WebGLRenderer對象,使用計算機的圖形卡來渲染場景。
renderer.setClearColor(0xEEEEEE,0.5);
renderer.setSize(window.innerWidth,window.innerHeight);
接下來通過renderer的setClearColor函數來設置renderer的背景色為接近白色的顏色(0xEEEEEE),并通過setSize()函數來告訴renderer將scene渲染為多大的尺寸。
通過以上的代碼,我們有了一個空白的scene、一個renderer和一個camera。
下面我們來創建一個坐標軸對象,并添加到場景中。
var axes=new THREE.AxisHelper(20);
scene.add(axes);
通過THREE的AxisHelper函數我們創建了一個長度為20的坐標軸,并通過scene的add函數將其添加到了場景中。
下面我們再創建一個平面(plane)并修改其旋轉和位置。
var planeGeometry = new THREE.PlaneGeometry(60,20,1,1);
var planeMaterial = new THREE.MeshBasicMaterial({color:0xcccccc});
var plane=new THREE.Mesh(planeGeometry,planeMaterial);
plane.rotation.x=-0.5*Math.PI;
plane.position.x=15;plane.position.y=0;plane.position.z=0;
scene.add(plane);
首先通過THREE.PlaneGeometry(60,20)來定義該平面的尺寸,在該章節中,我們將平面的尺寸設置為寬60,高20。在創建完幾何體之后我們還需要給plane指定材質,在這里我們使用MeshBasicMaterial()方法來創建一個基本的材質,其顏色為0xcccccc。接下來將兩個對象合并到一個名為plane的Mesh(網格)對象中。在將其放入場景之前還要修改其旋轉和位置,先將其繞著x軸旋轉90度,然后修改其position的x、y和z分量,最后將其加入scene中。
最后
camera.position.x=-30;camera.position.y=40;camera.position.z=30;
camera.lookAt(scene.position);
$("#WebGL-output").append(renderer.domElement);
renderer.render(scene,camera);
我們通過修改camera的位置和使用LookAt函數(對Unity和OpenGL熟悉的應該對此也不陌生)來修改camera的位置和朝向。在這里,我們的lookAt函數指向scene的中心。
最后,我們應該將renderer的輸出掛接到HTML頁面框架中的<div>元素中;在這里我們使用jQuery來選擇正確的輸出元素,并告訴 renderer用我們提供的相機來渲染scene。
《添加材質、燈光和陰影》
由于線框的渲染模式不會對燈光產生反應,因此我們需要修改cube和sphere的材質。
先將上一節的例子復制,并改名。
在創建完renderer之后,我們開始創建燈光:
var spotLight=new THREE.SpotLight(0xffffff);
spotLight.position.set(-40,60,-10);
scene.add(spotLight);
上述通過SpotLight()方法來創建的一個探照燈光源,并通過spotLight對象的position.set(-40,60,-10)位置來照射我們的場景。
修改Material的類型為Lambert材質:
var planeGeometry = new THREE.PlaneGeometry(60,20,1,1);
var planeMaterial = new THREE.MeshLambertMaterial({color:0xffffff});
同時修改cube和sphere的材質類型
同理,我們也可以使用Phong光照模型來產生光照效果,MeshPhongMaterial();
最后,我們開始添加陰影。因為陰影的計算比較消耗計算資源,因此默認情況下Three.js不會渲染陰影。
我們在renderer下面加入
renderer.shadowMapEnabled=true;
在plane創建完成之后加入
plane.receiveShadow=true;
cube.castShadow=true;
sphere.castShadow=true;
spotLight.castShadow=true;
來使其接收陰影。
最后產生的效果如下圖:
該節的整體代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example 01.03 - Light and shadow</title>
<script type="text/javascript"
src="../libs/three.js"></script>
<script type="text/javascript"
src="../libs/jquery-3.1.1.js"></script>
<style>
body{
/*set margin to 0 and overflow to hidden,to use the complete page*/
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<!--Div which will hold the Output-->
<div id="WebGL-output">
</div>
<!--Javascript code that runs out Three.js examples-->
<script type="text/javascript">
//once everything is loaded, we run out Three.js stuff.
$(function () {
var scene=new THREE.Scene();
var camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);
var renderer=new THREE.WebGLRenderer();
renderer.setClearColor(0xEEEEEE,0.5);
renderer.setSize(window.innerWidth,window.innerHeight);
renderer.shadowMapType=THREE.PCFSoftShadowMap;
renderer.shadowMapEnabled=true;
var spotLight=new THREE.SpotLight(0xffffff);
spotLight.position.set(-40,60,-10);
spotLight.castShadow=true;
spotLight.shadowMapHeight=4096;
spotLight.shadowMapWidth=4096;
scene.add(spotLight);
var ambientLight=new THREE.AmbientLight(0xffffff);
ambientLight.intensity=0.3;
scene.add(ambientLight);
var axes=new THREE.AxisHelper(20);
scene.add(axes);
var planeGeometry = new THREE.PlaneGeometry(60,20,1,1);
var planeMaterial = new THREE.MeshPhongMaterial({color:0xffffff});
var plane=new THREE.Mesh(planeGeometry,planeMaterial);
plane.rotation.x=-0.5*Math.PI;
plane.position.x=15;plane.position.y=0;plane.position.z=0;
plane.receiveShadow=true;
scene.add(plane);
var cubeGeometry = new THREE.CubeGeometry(4,4,4);
var cubeMaterial = new THREE.MeshPhongMaterial({color:0xff0000});
var cube=new THREE.Mesh(cubeGeometry,cubeMaterial);
cube.position.x=-4;cube.position.y=3;cube.position.z=0;
cube.castShadow=true;
scene.add(cube);
var sphereGeometry=new THREE.SphereGeometry(4,20,20);
var sphereMaterial=new THREE.MeshPhongMaterial({color:0x7777ff});
var sphere=new THREE.Mesh(sphereGeometry,sphereMaterial);
sphere.position.x=20;sphere.position.y=4;sphere.position.z=2;
sphere.castShadow=true;
scene.add(sphere);
camera.position.x=-30;camera.position.y=40;camera.position.z=30;
camera.lookAt(scene.position);
$("#WebGL-output").append(renderer.domElement);
renderer.render(scene,camera);
});
</script>
</body>
</html>
《簡單的動畫和幀率監控》
在Three.js中,使用requestAnimationFrame()方法可以指定一個渲染函數,按照瀏覽器的時間間隔(通常是每秒60幀)來調用該函數。在指定的渲染函數中,可以對場景中的物體的位置 、旋轉和縮放等進行更新。
那么在進行動畫之前,我們先來引入幀率檢測的代碼。首先在HTML頁面引入stats.js這個庫。
<script type="text/javascript" src="../libs/stats.js"></script>
然后再添加一個用于展示統計信息的div
<div id="Stats-output"></div>
最后編寫初始化stats的代碼:
function initStats() {
var stats=new Stats();
stats.setMode(0);
stats.domElement.style.position='absolute';
stats.domElement.style.left='0px';
stats.domElement.style.top='0px';
document.getElementById("Stats-output").appendChild(stats.domElement);
return stats;
}
并在主體代碼的開頭引入stats對象
var stats=initStats();
下面,我們來編寫每一幀需要調用的渲染函數
function renderScene() {
stats.update();
//animate cube
cube.rotation.x+=0.02;cube.rotation.y+=0.02;cube.rotation.z+=0.02;
//animate sphere
step+=0.04;
sphere.position.x=20+(10*Math.cos(step));
sphere.position.y=2+(10*Math.abs(Math.sin(step)));
requestAnimationFrame(renderScene);
renderer.render(scene,camera);
}
該渲染函數在每次調用會更新stats信息,更新方塊的旋轉和球體的運動位置。最后通過requestAnimationFrame函數來指定renderScene函數為指定時間間隔渲染的函數。最后調用renderer渲染器的render函數重新渲染。
最后我們在代碼的主體加入一次對renderScene函數的調用。
本節所有代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example 01.04 - Simple Animation</title>
<script type="text/javascript" src="../libs/three.js"></script>
<script type="text/javascript" src="../libs/jquery-3.1.1.js"></script>
<script type="text/javascript" src="../libs/stats.js"></script>
<style>
body{
/*set margin to 0 and overflow to hidden,to use the complete page*/
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="Stats-output"></div>
<!--Div which will hold the Output-->
<div id="WebGL-output"></div>
<!--Javascript code that runs out Three.js examples-->
<script type="text/javascript">
//once everything is loaded, we run out Three.js stuff.
function init() {
var scene=new THREE.Scene();
var camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);
var renderer=new THREE.WebGLRenderer();
var stats=initStats();
renderer.setClearColor(0xEEEEEE,0.5);
renderer.setSize(window.innerWidth,window.innerHeight);
renderer.shadowMapType=THREE.PCFSoftShadowMap;
renderer.shadowMapEnabled=true;
var spotLight=new THREE.SpotLight(0xffffff);
spotLight.position.set(-40,60,-10);
spotLight.castShadow=true;
spotLight.shadowMapHeight=4096;
spotLight.shadowMapWidth=4096;
scene.add(spotLight);
var ambientLight=new THREE.AmbientLight(0xffffff);
ambientLight.intensity=0.3;
scene.add(ambientLight);
var axes=new THREE.AxisHelper(20);
scene.add(axes);
var planeGeometry = new THREE.PlaneGeometry(60,20,1,1);
var planeMaterial = new THREE.MeshPhongMaterial({color:0xffffff});
var plane=new THREE.Mesh(planeGeometry,planeMaterial);
plane.rotation.x=-0.5*Math.PI;
plane.position.x=15;plane.position.y=0;plane.position.z=0;
plane.receiveShadow=true;
scene.add(plane);
var cubeGeometry = new THREE.CubeGeometry(4,4,4);
var cubeMaterial = new THREE.MeshPhongMaterial({color:0xff0000});
var cube=new THREE.Mesh(cubeGeometry,cubeMaterial);
cube.position.x=-4;cube.position.y=3;cube.position.z=0;
cube.castShadow=true;
scene.add(cube);
var sphereGeometry=new THREE.SphereGeometry(4,20,20);
var sphereMaterial=new THREE.MeshPhongMaterial({color:0x7777ff});
var sphere=new THREE.Mesh(sphereGeometry,sphereMaterial);
sphere.position.x=20;sphere.position.y=4;sphere.position.z=2;
sphere.castShadow=true;
scene.add(sphere);
camera.position.x=-30;camera.position.y=40;camera.position.z=30;
camera.lookAt(scene.position);
document.getElementById("WebGL-output").appendChild(renderer.domElement);
renderer.render(scene,camera);
renderScene();
var step=0;
function renderScene() {
stats.update();
//animate cube
cube.rotation.x+=0.02;cube.rotation.y+=0.02;cube.rotation.z+=0.02;
//animate sphere
step+=0.04;
sphere.position.x=20+(10*Math.cos(step));
sphere.position.y=2+(10*Math.abs(Math.sin(step)));
requestAnimationFrame(renderScene);
renderer.render(scene,camera);
}
function initStats() {
var stats=new Stats();
stats.setMode(0);
stats.domElement.style.position='absolute';
stats.domElement.style.left='0px';
stats.domElement.style.top='0px';
document.getElementById("Stats-output").appendChild(stats.domElement);
return stats;
}
}
window.onload=init;
</script>
</body>
</html>
《使用dat.GUI來編寫一個簡單的UI》
dat.GUI為Google公司的一些人創建的庫,該庫的文檔(http://code.google.com/p/dat-gui/ 需翻墻)通過這個庫,我們可以實現用slider滑動條來控制立方體的自旋速度和球體的彈跳速度。
首先需要引用dat.GUI.js庫
<script type="text/javascript" src="../libs/dat.gui.js"></script>
接下來添加一個JavaScript對象:
var controls = new function () {
this.rotationSpeed = 0.02;
this.bouncingSpeed = 0.03;
};
然后創建一個gui對象并添加控制器:
var gui=new dat.GUI();
gui.add(controls,'rotationSpeed',0,0.5);
gui.add(controls,'bouncingSpeed',0,0.5);
注意,這些代碼需要寫在渲染函數之前。
接下來修改上一節的renderScene函數中的方塊和球體的動畫控制代碼:
function renderScene() {
stats.update();
//animate cube
cube.rotation.x+=controls.rotationSpeed;cube.rotation.y+=controls.rotationSpeed;cube.rotation.z+=controls.rotationSpeed;
//animate sphere
step+=controls.bouncingSpeed;
sphere.position.x=20+(10*Math.cos(step));
sphere.position.y=2+(10*Math.abs(Math.sin(step)));
requestAnimationFrame(renderScene);
renderer.render(scene,camera);
}
編寫完成之后運行效果如下:
本節的完整代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example 01.05 - dat.GUI UserInterface</title>
<script type="text/javascript" src="../libs/three.js"></script>
<script type="text/javascript" src="../libs/jquery-3.1.1.js"></script>
<script type="text/javascript" src="../libs/stats.js"></script>
<script type="text/javascript" src="../libs/dat.gui.js"></script>
<style>
body{
/*set margin to 0 and overflow to hidden,to use the complete page*/
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="Stats-output"></div>
<!--Div which will hold the Output-->
<div id="WebGL-output"></div>
<!--Javascript code that runs out Three.js examples-->
<script type="text/javascript">
//once everything is loaded, we run out Three.js stuff.
function init() {
var scene=new THREE.Scene();
var camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);
var renderer=new THREE.WebGLRenderer();
var stats=initStats();
renderer.setClearColor(0xEEEEEE,0.5);
renderer.setSize(window.innerWidth,window.innerHeight);
renderer.shadowMapType=THREE.PCFSoftShadowMap;
renderer.shadowMapEnabled=true;
var spotLight=new THREE.SpotLight(0xffffff);
spotLight.position.set(-40,60,-10);
spotLight.castShadow=true;
spotLight.shadowMapHeight=4096;
spotLight.shadowMapWidth=4096;
scene.add(spotLight);
var ambientLight=new THREE.AmbientLight(0xffffff);
ambientLight.intensity=0.3;
scene.add(ambientLight);
var axes=new THREE.AxisHelper(20);
scene.add(axes);
var planeGeometry = new THREE.PlaneGeometry(60,20,1,1);
var planeMaterial = new THREE.MeshPhongMaterial({color:0xffffff});
var plane=new THREE.Mesh(planeGeometry,planeMaterial);
plane.rotation.x=-0.5*Math.PI;
plane.position.x=15;plane.position.y=0;plane.position.z=0;
plane.receiveShadow=true;
scene.add(plane);
var cubeGeometry = new THREE.CubeGeometry(4,4,4);
var cubeMaterial = new THREE.MeshPhongMaterial({color:0xff0000});
var cube=new THREE.Mesh(cubeGeometry,cubeMaterial);
cube.position.x=-4;cube.position.y=3;cube.position.z=0;
cube.castShadow=true;
scene.add(cube);
var sphereGeometry=new THREE.SphereGeometry(4,20,20);
var sphereMaterial=new THREE.MeshPhongMaterial({color:0x7777ff});
var sphere=new THREE.Mesh(sphereGeometry,sphereMaterial);
sphere.position.x=20;sphere.position.y=4;sphere.position.z=2;
sphere.castShadow=true;
scene.add(sphere);
camera.position.x=-30;camera.position.y=40;camera.position.z=30;
camera.lookAt(scene.position);
document.getElementById("WebGL-output").appendChild(renderer.domElement);
renderer.render(scene,camera);
var controls = new function () {
this.rotationSpeed = 0.02;
this.bouncingSpeed = 0.03;
};
var gui=new dat.GUI();
gui.add(controls,'rotationSpeed',0,0.5);
gui.add(controls,'bouncingSpeed',0,0.5);
//this renderScene() function should be called after every
renderScene();
var step=0;
function renderScene() {
stats.update();
//animate cube
cube.rotation.x+=controls.rotationSpeed;cube.rotation.y+=controls.rotationSpeed;cube.rotation.z+=controls.rotationSpeed;
//animate sphere
step+=controls.bouncingSpeed;
sphere.position.x=20+(10*Math.cos(step));
sphere.position.y=2+(10*Math.abs(Math.sin(step)));
requestAnimationFrame(renderScene);
renderer.render(scene,camera);
}
function initStats() {
var stats=new Stats();
stats.setMode(0);
stats.domElement.style.position='absolute';
stats.domElement.style.left='0px';
stats.domElement.style.top='0px';
document.getElementById("Stats-output").appendChild(stats.domElement);
return stats;
}
}
window.onload=init;
</script>
</body>
</html>
《動態改變渲染大小》
在使用Three.js的時候,我們還可以根據窗口大小的改變來調整渲染的大小。
在這里我們需要添加一個onSizeChanged函數
function onSizeChanged() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
編寫完該函數之后我們需要對窗口大小改變的事件增加監聽:
window.addEventListener('resize', onSizeChanged, false);
注意,這里要把renderer、camera等變量定義成作用域更廣的變量,具體參見詳細代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example 01.06 - Resize</title>
<script type="text/javascript" src="../libs/three.js"></script>
<script type="text/javascript" src="../libs/jquery-3.1.1.js"></script>
<script type="text/javascript" src="../libs/stats.js"></script>
<script type="text/javascript" src="../libs/dat.gui.js"></script>
<style>
body{
/*set margin to 0 and overflow to hidden,to use the complete page*/
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="Stats-output"></div>
<!--Div which will hold the Output-->
<div id="WebGL-output"></div>
<!--Javascript code that runs out Three.js examples-->
<script type="text/javascript">
//once everything is loaded, we run out Three.js stuff.
var scene;
var camera;
var stats;
var renderer;
function init() {
scene=new THREE.Scene();
camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);
renderer=new THREE.WebGLRenderer();
stats=initStats();
renderer.setClearColor(0xEEEEEE,0.5);
renderer.setSize(window.innerWidth,window.innerHeight);
renderer.shadowMapType=THREE.PCFSoftShadowMap;
renderer.shadowMapEnabled=true;
var spotLight=new THREE.SpotLight(0xffffff);
spotLight.position.set(-40,60,-10);
spotLight.castShadow=true;
spotLight.shadowMapHeight=4096;
spotLight.shadowMapWidth=4096;
scene.add(spotLight);
var ambientLight=new THREE.AmbientLight(0xffffff);
ambientLight.intensity=0.3;
scene.add(ambientLight);
var axes=new THREE.AxisHelper(20);
scene.add(axes);
var planeGeometry = new THREE.PlaneGeometry(60,20,1,1);
var planeMaterial = new THREE.MeshPhongMaterial({color:0xffffff});
var plane=new THREE.Mesh(planeGeometry,planeMaterial);
plane.rotation.x=-0.5*Math.PI;
plane.position.x=15;plane.position.y=0;plane.position.z=0;
plane.receiveShadow=true;
scene.add(plane);
var cubeGeometry = new THREE.CubeGeometry(4,4,4);
var cubeMaterial = new THREE.MeshPhongMaterial({color:0xff0000});
var cube=new THREE.Mesh(cubeGeometry,cubeMaterial);
cube.position.x=-4;cube.position.y=3;cube.position.z=0;
cube.castShadow=true;
scene.add(cube);
var sphereGeometry=new THREE.SphereGeometry(4,20,20);
var sphereMaterial=new THREE.MeshPhongMaterial({color:0x7777ff});
var sphere=new THREE.Mesh(sphereGeometry,sphereMaterial);
sphere.position.x=20;sphere.position.y=4;sphere.position.z=2;
sphere.castShadow=true;
scene.add(sphere);
camera.position.x=-30;camera.position.y=40;camera.position.z=30;
camera.lookAt(scene.position);
document.getElementById("WebGL-output").appendChild(renderer.domElement);
//effect.render(scene,camera);
var controls = new function () {
this.rotationSpeed = 0.02;
this.bouncingSpeed = 0.03;
};
var gui=new dat.GUI();
gui.add(controls,'rotationSpeed',0,0.5);
gui.add(controls,'bouncingSpeed',0,0.5);
//this renderScene() function should be called after every
renderScene();
var step=0;
function renderScene() {
stats.update();
//animate cube
cube.rotation.x+=controls.rotationSpeed;cube.rotation.y+=controls.rotationSpeed;cube.rotation.z+=controls.rotationSpeed;
//animate sphere
step+=controls.bouncingSpeed;
sphere.position.x=20+(10*Math.cos(step));
sphere.position.y=2+(10*Math.abs(Math.sin(step)));
requestAnimationFrame(renderScene);
renderer.render(scene,camera);
}
function initStats() {
var stats=new Stats();
stats.setMode(0);
stats.domElement.style.position='absolute';
stats.domElement.style.left='0px';
stats.domElement.style.top='0px';
document.getElementById("Stats-output").appendChild(stats.domElement);
return stats;
}
}
function onResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
window.onload=init;
window.addEventListener('resize', onResize, false);
</script>
</body>
</html>
那么到這里,我們就完成了對Three.js的入門學習。下面我們會更加深入的講解Three.js。
參考資料:
Learning Three.js The JavaSctipt 3D Library for WebGL ·Jos Dirksen