十分鐘快速實(shí)戰(zhàn)Three.js
前言
本文不會(huì)對(duì)Three.js幾何體、材質(zhì)、相機(jī)、模型、光源等概念詳細(xì)講解,會(huì)首先分成幾個(gè)模塊給大家快速演示一盒小案例。大家可以根據(jù)這幾個(gè)模塊快速了解Three.js的無(wú)限魅力。
學(xué)習(xí)
我們會(huì)使用Three.js簡(jiǎn)單做一個(gè)立方體,為了大家更能宏觀的了解Three.js。我將會(huì)分解成代碼段(模塊)來(lái)進(jìn)行開發(fā)。
模塊如下:
場(chǎng)景對(duì)象
網(wǎng)格模型
光源
相機(jī)
渲染器對(duì)象
渲染操作
1. 創(chuàng)建html文件
首先,我們得創(chuàng)建一個(gè)html文件,這樣才有地方開發(fā)。創(chuàng)建完成后,我們可以引入Three.js文件,今天,它可是主角。我是直接引入遠(yuǎn)程URL地址進(jìn)行加載,你也可以去官網(wǎng)進(jìn)行下載到本地引入。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>three.js小案例</title>
<!--引入three.js-->
<script src="https://unpkg.com/three@0.122.0/build/three.js"></script>
</head>
<body>
</body>
</html>
2. 創(chuàng)建場(chǎng)景對(duì)象
借助Three.js引擎創(chuàng)建好一個(gè)虛擬的三維場(chǎng)景。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>three.js小案例</title>
<!--引入three.js-->
<script src="https://unpkg.com/three@0.122.0/build/three.js"></script>
</head>
<body>
<script>
/*
* 創(chuàng)建場(chǎng)景對(duì)象Scene
*/
var scene = new THREE.Scene();
</script>
</body>
</html>
3. 創(chuàng)建網(wǎng)格模型
這行代碼new THREE.BoxGeometry(200, 200, 200)的意思是創(chuàng)建了一個(gè)長(zhǎng)200、寬200、高200的立方體對(duì)象。然后并通過(guò)代碼new THREE.MeshLambertMaterial給立方體對(duì)象定義材質(zhì),這里可以理解成立方體的屬性(包含了顏色、透明度等屬性),這里暫時(shí)列舉顏色屬性。然后我們需要將立方體與屬性聯(lián)系起來(lái),就用到網(wǎng)格模型,將兩者作為構(gòu)造函數(shù)Mesh的兩個(gè)參數(shù)傳進(jìn)去,最后添加到場(chǎng)景里面。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>three.js小案例</title>
<!--引入three.js-->
<script src="https://unpkg.com/three@0.122.0/build/three.js"></script>
</head>
<body>
<script>
/*
* 創(chuàng)建場(chǎng)景對(duì)象
*/
var scene = new THREE.Scene();
/*
* 創(chuàng)建網(wǎng)格模型
*/
var geometry = new THREE.BoxGeometry(200, 200, 200); //創(chuàng)建一個(gè)立方體幾何對(duì)象Geometry
var material = new THREE.MeshLambertMaterial({
color: '#f4f4f4',
}); //材質(zhì)對(duì)象Material
var mesh = new THREE.Mesh(geometry, material); //網(wǎng)格模型對(duì)象Mesh
scene.add(mesh); //網(wǎng)格模型添加到場(chǎng)景中
</script>
</body>
</html>
4. 設(shè)置光源
代碼new THREE.PointLight('#fff')創(chuàng)建了一個(gè)點(diǎn)光源對(duì)象,參數(shù)#fff定義的是光照強(qiáng)度, 你可以嘗試把參數(shù)更改為#666,你會(huì)看到立方體的表面顏色變暗,這很好理解,實(shí)際生活中燈光強(qiáng)度變低了,周圍的景物自然暗淡。比如夜空中的照明彈就是一個(gè)點(diǎn)光源例子。代碼THREE.AmbientLight('#333')創(chuàng)建了一個(gè)環(huán)境光對(duì)象,環(huán)境光的顏色會(huì)影響到整個(gè)場(chǎng)景,環(huán)境光沒有特定的光源,是模擬漫反射的一種光源,因此不需要指定位置它能將燈光均勻地照射在場(chǎng)景中每個(gè)物體上面,一般情況下用來(lái)弱化陰影或者添加一些顏色到環(huán)境中,因此不能將環(huán)境光作為場(chǎng)景中的唯一光源。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>three.js小案例</title>
<!--引入three.js-->
<script src="https://unpkg.com/three@0.122.0/build/three.js"></script>
</head>
<body>
<script>
/*
* 創(chuàng)建場(chǎng)景對(duì)象
*/
var scene = new THREE.Scene();
/*
* 創(chuàng)建網(wǎng)格模型
*/
var geometry = new THREE.BoxGeometry(200, 200, 200); //創(chuàng)建一個(gè)立方體幾何對(duì)象Geometry
var material = new THREE.MeshLambertMaterial({
color: '#f4f4f4',
}); //材質(zhì)對(duì)象Material
var mesh = new THREE.Mesh(geometry, material); //網(wǎng)格模型對(duì)象Mesh
scene.add(mesh); //網(wǎng)格模型添加到場(chǎng)景中
/*
* 設(shè)置光源
*/
var point = new THREE.PointLight('#fff'); //點(diǎn)光源
point.position.set(300, 100, 200); //點(diǎn)光源位置
scene.add(point); //點(diǎn)光源添加到場(chǎng)景中
var ambient = new THREE.AmbientLight('#333');//環(huán)境光
scene.add(ambient); //環(huán)境光添加到場(chǎng)景中
</script>
</body>
</html>
5.設(shè)置相機(jī)
代碼new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000)創(chuàng)建了一個(gè)正射投影相機(jī)對(duì)象, 什么是“正射投影”,什么是“相機(jī)對(duì)象”, 比如把該構(gòu)造函數(shù)參數(shù)中用到的參數(shù)s,也就是代碼var s = 200中定義的一個(gè)系數(shù),可以把200更改為300,你會(huì)發(fā)現(xiàn)立方體顯示效果變小,這很好理解,相機(jī)構(gòu)造函數(shù)的的前四個(gè)參數(shù)定義的是拍照窗口大小, 就像平時(shí)拍照一樣,取景范圍為大,被拍的人相對(duì)背景自然變小了。camera.position.set(200, 300, 200);和camera.lookAt(scene.position)定義的是相機(jī)的位置和拍照方向,可以更改camera.position.set(200,300,200)參數(shù)重新定義的相機(jī)位置,把第一個(gè)參數(shù)也就是x坐標(biāo)從200更改為250, 你會(huì)發(fā)現(xiàn)立方的在屏幕上呈現(xiàn)的角度變了,這就像你生活中拍照人是同一個(gè)人,但是你拍照的位置角度不同,顯示的效果肯定不同。這些具體的參數(shù)細(xì)節(jié)可以不用管, 至少你知道相機(jī)可以縮放顯示三維場(chǎng)景、對(duì)三維場(chǎng)景的不同角度進(jìn)行取景顯示。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>three.js小案例</title>
<!--引入three.js-->
<script src="https://unpkg.com/three@0.122.0/build/three.js"></script>
</head>
<body>
<script>
/*
* 創(chuàng)建場(chǎng)景對(duì)象
*/
var scene = new THREE.Scene();
/*
* 創(chuàng)建網(wǎng)格模型
*/
var geometry = new THREE.BoxGeometry(200, 200, 200); //創(chuàng)建一個(gè)立方體幾何對(duì)象Geometry
var material = new THREE.MeshLambertMaterial({
color: '#f4f4f4',
}); //材質(zhì)對(duì)象Material
var mesh = new THREE.Mesh(geometry, material); //網(wǎng)格模型對(duì)象Mesh
scene.add(mesh); //網(wǎng)格模型添加到場(chǎng)景中
/*
* 設(shè)置光源
*/
var point = new THREE.PointLight('#fff'); //點(diǎn)光源
point.position.set(300, 100, 200); //點(diǎn)光源位置
scene.add(point); //點(diǎn)光源添加到場(chǎng)景中
var ambient = new THREE.AmbientLight('#333');//環(huán)境光
scene.add(ambient); //環(huán)境光添加到場(chǎng)景中
/*
* 設(shè)置相機(jī)
*/
var width = window.innerWidth; //窗口寬度
var height = window.innerHeight; //窗口高度
var k = width / height; //窗口寬高比
var s = 200; //三維場(chǎng)景顯示范圍控制系數(shù),系數(shù)越大,顯示的范圍越大
//創(chuàng)建相機(jī)對(duì)象
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(200, 300, 200); //設(shè)置相機(jī)位置
camera.lookAt(scene.position); //設(shè)置相機(jī)方向(指向的場(chǎng)景對(duì)象)
</script>
</body>
</html>
6.創(chuàng)建渲染器對(duì)象
Three.js是基于原生WebGL封裝運(yùn)行的三維引擎。所以瀏覽器利用代碼new THREE.WebGLRenderer()就會(huì)渲染出一幀圖像??梢栽O(shè)置渲染區(qū)域尺寸和背景顏色。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>three.js小案例</title>
<!--引入three.js-->
<script src="https://unpkg.com/three@0.122.0/build/three.js"></script>
</head>
<body>
<script>
/*
* 創(chuàng)建場(chǎng)景對(duì)象
*/
var scene = new THREE.Scene();
/*
* 創(chuàng)建網(wǎng)格模型
*/
var geometry = new THREE.BoxGeometry(200, 200, 200); //創(chuàng)建一個(gè)立方體幾何對(duì)象Geometry
var material = new THREE.MeshLambertMaterial({
color: '#f4f4f4',
}); //材質(zhì)對(duì)象Material
var mesh = new THREE.Mesh(geometry, material); //網(wǎng)格模型對(duì)象Mesh
scene.add(mesh); //網(wǎng)格模型添加到場(chǎng)景中
/*
* 設(shè)置光源
*/
var point = new THREE.PointLight('#fff'); //點(diǎn)光源
point.position.set(300, 100, 200); //點(diǎn)光源位置
scene.add(point); //點(diǎn)光源添加到場(chǎng)景中
var ambient = new THREE.AmbientLight('#333');//環(huán)境光
scene.add(ambient); //環(huán)境光添加到場(chǎng)景中
/*
* 設(shè)置相機(jī)
*/
var width = window.innerWidth; //窗口寬度
var height = window.innerHeight; //窗口高度
var k = width / height; //窗口寬高比
var s = 200; //三維場(chǎng)景顯示范圍控制系數(shù),系數(shù)越大,顯示的范圍越大
//創(chuàng)建相機(jī)對(duì)象
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(200, 300, 200); //設(shè)置相機(jī)位置
camera.lookAt(scene.position); //設(shè)置相機(jī)方向(指向的場(chǎng)景對(duì)象)
/*
* 創(chuàng)建渲染器對(duì)象
*/
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height); //設(shè)置渲染區(qū)域尺寸
renderer.setClearColor(0xb9d3ff, 1); //設(shè)置背景顏色
</script>
</body>
</html>
7.執(zhí)行渲染操作
將渲染好的區(qū)域指定場(chǎng)景、相機(jī)作為參數(shù),并且把區(qū)域添加到頁(yè)面上。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>three.js小案例</title>
<!--引入three.js-->
<script src="https://unpkg.com/three@0.122.0/build/three.js"></script>
</head>
<body>
<script>
/*
* 創(chuàng)建場(chǎng)景對(duì)象
*/
var scene = new THREE.Scene();
/*
* 創(chuàng)建網(wǎng)格模型
*/
var geometry = new THREE.BoxGeometry(200, 200, 200); //創(chuàng)建一個(gè)立方體幾何對(duì)象Geometry
var material = new THREE.MeshLambertMaterial({
color: '#f4f4f4',
}); //材質(zhì)對(duì)象Material
var mesh = new THREE.Mesh(geometry, material); //網(wǎng)格模型對(duì)象Mesh
scene.add(mesh); //網(wǎng)格模型添加到場(chǎng)景中
/*
* 設(shè)置光源
*/
var point = new THREE.PointLight('#fff'); //點(diǎn)光源
point.position.set(300, 100, 200); //點(diǎn)光源位置
scene.add(point); //點(diǎn)光源添加到場(chǎng)景中
var ambient = new THREE.AmbientLight('#333');//環(huán)境光
scene.add(ambient); //環(huán)境光添加到場(chǎng)景中
/*
* 設(shè)置相機(jī)
*/
var width = window.innerWidth; //窗口寬度
var height = window.innerHeight; //窗口高度
var k = width / height; //窗口寬高比
var s = 200; //三維場(chǎng)景顯示范圍控制系數(shù),系數(shù)越大,顯示的范圍越大
//創(chuàng)建相機(jī)對(duì)象
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(200, 300, 200); //設(shè)置相機(jī)位置
camera.lookAt(scene.position); //設(shè)置相機(jī)方向(指向的場(chǎng)景對(duì)象)
/*
* 創(chuàng)建渲染器對(duì)象
*/
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height); //設(shè)置渲染區(qū)域尺寸
renderer.setClearColor(0xb9d3ff, 1); //設(shè)置背景顏色
/*
* 執(zhí)行渲染操作
*/
renderer.render(scene, camera); //指定場(chǎng)景、相機(jī)作為參數(shù)
document.body.appendChild(renderer.domElement); //body元素中插入canvas對(duì)象
</script>
</body>
</html>
完整代碼
代碼body {margin: 0;overflow: hidden;}是為了隱藏body窗口區(qū)域滾動(dòng)條。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>three.js小案例</title>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
<!--引入three.js-->
<script src="https://unpkg.com/three@0.122.0/build/three.js"></script>
</head>
<body>
<script>
/*
* 創(chuàng)建場(chǎng)景對(duì)象
*/
var scene = new THREE.Scene();
/*
* 創(chuàng)建網(wǎng)格模型
*/
var geometry = new THREE.BoxGeometry(200, 200, 200); //創(chuàng)建一個(gè)立方體幾何對(duì)象Geometry
var material = new THREE.MeshLambertMaterial({
color: '#f4f4f4',
}); //材質(zhì)對(duì)象Material
var mesh = new THREE.Mesh(geometry, material); //網(wǎng)格模型對(duì)象Mesh
scene.add(mesh); //網(wǎng)格模型添加到場(chǎng)景中
/*
* 設(shè)置光源
*/
var point = new THREE.PointLight('#fff'); //點(diǎn)光源
point.position.set(300, 100, 200); //點(diǎn)光源位置
scene.add(point); //點(diǎn)光源添加到場(chǎng)景中
var ambient = new THREE.AmbientLight('#333');//環(huán)境光
scene.add(ambient); //環(huán)境光添加到場(chǎng)景中
/*
* 設(shè)置相機(jī)
*/
var width = window.innerWidth; //窗口寬度
var height = window.innerHeight; //窗口高度
var k = width / height; //窗口寬高比
var s = 200; //三維場(chǎng)景顯示范圍控制系數(shù),系數(shù)越大,顯示的范圍越大
//創(chuàng)建相機(jī)對(duì)象
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(200, 300, 200); //設(shè)置相機(jī)位置
camera.lookAt(scene.position); //設(shè)置相機(jī)方向(指向的場(chǎng)景對(duì)象)
/*
* 創(chuàng)建渲染器對(duì)象
*/
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height); //設(shè)置渲染區(qū)域尺寸
renderer.setClearColor(0xb9d3ff, 1); //設(shè)置背景顏色
/*
* 執(zhí)行渲染操作
*/
renderer.render(scene, camera); //指定場(chǎng)景、相機(jī)作為參數(shù)
document.body.appendChild(renderer.domElement); //body元素中插入canvas對(duì)象
</script>
</body>
</html>
作者:Vam的金豆之路
主要領(lǐng)域:前端開發(fā)
我的微信:maomin9761
微信公眾號(hào):前端歷劫之路