Three.js學(xué)習(xí)之Lamber材質(zhì)和Phong材質(zhì)
前言
材質(zhì)(Material)是獨(dú)立于物體頂點(diǎn)信息之外的與渲染效果相關(guān)的屬性。通過設(shè)置材質(zhì)可以改變物體的顏色、紋理貼圖、光照模式等。
MeshBasicMaterial:對光照無感,給幾何體一種簡單的顏色或顯示線框。
MeshLambertMaterial:這種材質(zhì)對光照有反應(yīng),用于創(chuàng)建暗淡的不發(fā)光的物體。
MeshPhongMaterial:這種材質(zhì)對光照也有反應(yīng),用于創(chuàng)建金屬類明亮的物體。
1.基本材質(zhì)
使用基本材質(zhì)(BasicMaterial)的物體,渲染后物體的顏色始終為該材質(zhì)的顏色,而不會(huì)由于光照產(chǎn)生明暗、陰影效果。如果沒有指定材質(zhì)的顏色,則顏色是隨機(jī)的。其構(gòu)造函數(shù)是:
THREE.MeshLambertMaterial(opt)
其中,opt可以缺省,或者為包含各屬性的值。如新建一個(gè)不透明度為0.75的黃色材質(zhì):
new THREE.MeshBasicMaterial({
color: 0xffff00,
opacity: 0.75
});
將其應(yīng)用于一個(gè)正方體(方法參見《Three.js學(xué)習(xí)之幾何形狀》,效果為:

源碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>3.js測試7.1</title>
</head>
<body onload="init()">
<canvas id="mainCanvas" width="400px" height="300px" ></canvas>
</body>
<script type="text/javascript" src="js/three.min.js"></script>
<script type="text/javascript">
function init() {
var renderer = new THREE.WebGLRenderer({
canvas: document.getElementById('mainCanvas')
});
renderer.setClearColor(0x000000);
var scene = new THREE.Scene();
// camera
var camera = new THREE.OrthographicCamera(-5, 5, 3.75, -3.75, 0.1, 100);
camera.position.set(25, 25, 25);
camera.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(camera);
// light
var light = new THREE.PointLight(0xffffff, 1, 100);
light.position.set(10, 15, 5);
scene.add(light);
var material = new THREE.MeshBasicMaterial({
color: 0xffff00,
opacity: 0.75
});
var cube = new THREE.Mesh(new THREE.CubeGeometry(5, 5, 5), material);
scene.add(cube);
renderer.render(scene, camera);
}
</script>
</html>
BasicMaterial的幾個(gè)較為常用的屬性:
· visible:是否可見,默認(rèn)為true
· side:渲染面片正面或是反面,默認(rèn)為正面THREE.FrontSide,可設(shè)置為反面THREE.BackSide,或雙面THREE.DoubleSide
· wireframe:是否渲染線而非面,默認(rèn)為false
· color:十六進(jìn)制RGB顏色,如紅色表示為0xff0000
· map:使用紋理貼圖
對于基本材質(zhì),即使改變場景中的光源,使用該材質(zhì)的物體也始終為顏色處處相同的效果。當(dāng)然,這不是很具有真實(shí)感,因此,接下來我們將介紹更為真實(shí)的光照模型:Lambert光照模型以及Phong光照模型。
2.Lamber材質(zhì)與Phong材質(zhì)
Lambert材質(zhì)(MeshLambertMaterial)是符合Lambert光照模型的材質(zhì)。Lambert光照模型的主要特點(diǎn)是只考慮漫反射而不考慮鏡面反射的效果,因而對于金屬、鏡子等需要鏡面反射效果的物體就不適應(yīng),對于其他大部分物體的漫反射效果都是適用的。
其光照模型公式為:
Idiffuse = Kd * Id * cos(theta)
其中,Idiffuse是漫反射光強(qiáng),Kd是物體表面的漫反射屬性,Id是光強(qiáng),theta是光的入射角弧度。
當(dāng)然,對于使用Three.js的Lambert材質(zhì),不需要了解以上公式就可以直接使用。
創(chuàng)建一個(gè)黃色的Lambert材質(zhì)的方法為:
new THREE.MeshLambertMaterial({
color: 0xffff00
})
在使用了光照之后,得到這樣的效果:

color是用來表現(xiàn)材質(zhì)對散射光的反射能力,也是最常用來設(shè)置材質(zhì)顏色的屬性。除此之外,還可以用ambient和emissive控制材質(zhì)的顏色。
ambient表示對環(huán)境光的反射能力,只有當(dāng)設(shè)置了AmbientLight后,該值才是有效的,材質(zhì)對環(huán)境光的反射能力與環(huán)境光強(qiáng)相乘后得到材質(zhì)實(shí)際表現(xiàn)的顏色。
emissive是材質(zhì)的自發(fā)光顏色,可以用來表現(xiàn)光源的顏色,并不是一種光源,而是一種不受光照影響的顏色。單獨(dú)使用紅色的自發(fā)光:
new THREE.MeshLambertMaterial({
emissive: 0xff0000
})
效果為:

如果同時(shí)使用紅色的自發(fā)光與黃色的散射光:
new THREE.MeshLambertMaterial({
color: 0xffff00,
emissive: 0xff0000
})
效果為:

球體的效果:

總結(jié)Lamber材質(zhì)的特有屬性:
ambient:設(shè)置材質(zhì)的環(huán)境色,和AmbientLight光源一起使用,這個(gè)顏色會(huì)與環(huán)境光的顏色相乘。即是對光源作出反應(yīng)。
emissive:設(shè)置材質(zhì)發(fā)射的顏色,不是一種光源,而是一種不受光照影響的顏色。默認(rèn)為黑色。
源碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>3.js測試7.2</title>
</head>
<body onload="init()">
<canvas id="mainCanvas" width="400px" height="300px" ></canvas>
</body>
<script type="text/javascript" src="js/three.min.js"></script>
<script type="text/javascript">
function init() {
var renderer = new THREE.WebGLRenderer({
canvas: document.getElementById('mainCanvas')
});
renderer.setClearColor(0x000000);
var scene = new THREE.Scene();
// camera
var camera = new THREE.OrthographicCamera(-5, 5, 3.75, -3.75, 0.1, 100);
camera.position.set(25, 25, 25);
camera.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(camera);
// light
var light = new THREE.PointLight(0xffffff, 1, 100);
light.position.set(10, 15, 5);
scene.add(light);
var material = new THREE.MeshLambertMaterial({
color: 0xffff00,
emissive: 0xff0000
});
var cube = new THREE.Mesh(new THREE.CubeGeometry(5, 5, 5), material);
scene.add(cube);
// var sphere = new THREE.Mesh(new THREE.SphereGeometry(3, 20, 8), material);
// scene.add(sphere);
renderer.render(scene, camera);
}
</script>
</html>
3.phong材質(zhì)
Phong材質(zhì)(MeshPhongMaterial)是符合Phong光照模型的材質(zhì)。和Lambert不同的是,Phong模型考慮了鏡面反射的效果,因此對于金屬、鏡面的表現(xiàn)尤為適合。
漫反射部分和Lambert光照模型是相同的,鏡面反射部分的模型為:
Ispecular = Ks * Is * (cos(alpha)) ^ n
其中,Ispecular是鏡面反射的光強(qiáng),Ks是材質(zhì)表面鏡面反射系數(shù),Is是光源強(qiáng)度,alpha是反射光與視線的夾角,n是高光指數(shù),越大則高光光斑越小。
由于漫反射部分與Lambert模型是一致的,因此,如果不指定鏡面反射系數(shù),而只設(shè)定漫反射,其效果與Lambert是相同的:
new THREE.MeshPhongMaterial({
color: 0xffff00
});

同樣地,可以指定emissive和ambient值,這里不再說明。下面就specular值指定鏡面反射系數(shù)作說明。首先,我們只使用鏡面反射,將高光設(shè)為紅色,應(yīng)用于一個(gè)球體:
var material = new THREE.MeshPhongMaterial({
specular: 0xff0000
});
var sphere = new THREE.Mesh(new THREE.SphereGeometry(3, 20, 8), material);
效果為:

可以通過shininess屬性控制光照模型中的n值,當(dāng)shininess值越大時(shí),高光的光斑越小,默認(rèn)值為30。我們將其設(shè)置為1000時(shí):
new THREE.MeshPhongMaterial({
specular: 0xff0000,
shininess: 1000
});
效果為:

使用黃色的鏡面光,紅色的散射光:
material = new THREE.MeshPhongMaterial({
color: 0xff0000,
specular: 0xffff00,
shininess: 100
});
總結(jié)Phong材質(zhì)的特有屬性:
ambient:設(shè)置材質(zhì)的環(huán)境色,和AmbientLight光源一起使用,這個(gè)顏色會(huì)與環(huán)境光的顏色相乘。即是對光源作出反應(yīng)。
emissive:設(shè)置材質(zhì)發(fā)射的顏色,不是一種光源,而是一種不受光照影響的顏色。默認(rèn)為黑色
specular:指定該材質(zhì)的光亮程度及其高光部分的顏色,如果設(shè)置成和color屬性相同的顏色,則會(huì)得到另一個(gè)更加類似金屬的材質(zhì),如果設(shè)置成grey灰色,則看起來像塑料
shininess:指定高光部分的亮度,默認(rèn)值為30.
源碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>3.js測試7.3</title>
</head>
<body onload="init()">
<canvas id="mainCanvas" width="400px" height="300px" ></canvas>
</body>
<script type="text/javascript" src="js/three.min.js"></script>
<script type="text/javascript">
function init() {
var renderer = new THREE.WebGLRenderer({
canvas: document.getElementById('mainCanvas')
});
renderer.setClearColor(0x000000);
var scene = new THREE.Scene();
// camera
var camera = new THREE.OrthographicCamera(-5, 5, 3.75, -3.75, 0.1, 100);
camera.position.set(25, 25, 25);
camera.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(camera);
// light
var light = new THREE.PointLight(0xffffff, 1, 200);
light.position.set(10, 15, 25);
scene.add(light);
var material = new THREE.MeshPhongMaterial({
// specular: 0xff0000,
color: 0xff0000,
specular: 0xffff00,
shininess: 100
});
// var cube = new THREE.Mesh(new THREE.CubeGeometry(5, 5, 5), material);
// scene.add(cube);
var sphere = new THREE.Mesh(new THREE.SphereGeometry(3, 20, 8), material);
scene.add(sphere);
renderer.render(scene, camera);
}
</script>
</html>
總結(jié)
本文的內(nèi)容到這就結(jié)束了,文章通過詳細(xì)實(shí)例及圖片介紹了Three.js中的Lamber與Phong,希望對大家的學(xué)習(xí)有所幫助,小編會(huì)陸續(xù)整理Three.js的相關(guān)文章,對Three.js感興趣的朋友們請繼續(xù)支持腳本之家。
相關(guān)文章
精通JavaScript 糾正 cleanWhitespace函數(shù)
這個(gè)函數(shù)用在火狐(firefox)上面老是出錯(cuò),今天仔細(xì)研究了下,改正了,希望別人不要遇到我這樣的問題2010-03-03
Highcharts學(xué)習(xí)之?dāng)?shù)據(jù)列
數(shù)據(jù)列配置是 Highcharts 最復(fù)雜也是最靈活的配置,如果說 Highcharts 是靈活多變,細(xì)節(jié)可定制的話,那么數(shù)據(jù)列配置就是這個(gè)重要特性的核心。2016-08-08
Three.js學(xué)習(xí)之Lamber材質(zhì)和Phong材質(zhì)
本篇將介紹基本材質(zhì)以及兩種基于光照模型的材質(zhì)(Lamber與Phong),有需要的小伙伴們可以參考學(xué)習(xí)。2016-08-08
Three.js學(xué)習(xí)之文字形狀及自定義形狀
今天小編帶大家學(xué)習(xí)的是Three.js的文字形狀與自定義形狀,文章內(nèi)容很詳細(xì),對大家學(xué)習(xí)Three.js或許有幫助,下面一起來看看吧。2016-08-08
淺談JavaScript前端開發(fā)的MVC結(jié)構(gòu)與MVVM結(jié)構(gòu)
以AngularJS為代表的MVVM結(jié)構(gòu)框架或庫這兩年來在前端界真是火到不行,大有對抗傳統(tǒng)jQuery綁定思想的趨勢,這里我們結(jié)合傳統(tǒng)的MVC結(jié)構(gòu),來淺談JavaScript前端開發(fā)的MVC結(jié)構(gòu)與MVVM結(jié)構(gòu)2016-06-06

