Three.js學(xué)習(xí)之Lamber材質(zhì)和Phong材質(zhì)
前言
材質(zhì)(Material)是獨立于物體頂點信息之外的與渲染效果相關(guān)的屬性。通過設(shè)置材質(zhì)可以改變物體的顏色、紋理貼圖、光照模式等。
MeshBasicMaterial:對光照無感,給幾何體一種簡單的顏色或顯示線框。
MeshLambertMaterial:這種材質(zhì)對光照有反應(yīng),用于創(chuàng)建暗淡的不發(fā)光的物體。
MeshPhongMaterial:這種材質(zhì)對光照也有反應(yīng),用于創(chuàng)建金屬類明亮的物體。
1.基本材質(zhì)
使用基本材質(zhì)(BasicMaterial)的物體,渲染后物體的顏色始終為該材質(zhì)的顏色,而不會由于光照產(chǎn)生明暗、陰影效果。如果沒有指定材質(zhì)的顏色,則顏色是隨機(jī)的。其構(gòu)造函數(shù)是:
THREE.MeshLambertMaterial(opt)
其中,opt可以缺省,或者為包含各屬性的值。如新建一個不透明度為0.75的黃色材質(zhì):
new THREE.MeshBasicMaterial({ color: 0xffff00, opacity: 0.75 });
將其應(yīng)用于一個正方體(方法參見《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的幾個較為常用的屬性:
· 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)然,這不是很具有真實感,因此,接下來我們將介紹更為真實的光照模型:Lambert光照模型以及Phong光照模型。
2.Lamber材質(zhì)與Phong材質(zhì)
Lambert材質(zhì)(MeshLambertMaterial)是符合Lambert光照模型的材質(zhì)。Lambert光照模型的主要特點是只考慮漫反射而不考慮鏡面反射的效果,因而對于金屬、鏡子等需要鏡面反射效果的物體就不適應(yīng),對于其他大部分物體的漫反射效果都是適用的。
其光照模型公式為:
Idiffuse = Kd * Id * cos(theta)
其中,Idiffuse是漫反射光強(qiáng),Kd是物體表面的漫反射屬性,Id是光強(qiáng),theta是光的入射角弧度。
當(dāng)然,對于使用Three.js的Lambert材質(zhì),不需要了解以上公式就可以直接使用。
創(chuàng)建一個黃色的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ì)實際表現(xiàn)的顏色。
emissive是材質(zhì)的自發(fā)光顏色,可以用來表現(xiàn)光源的顏色,并不是一種光源,而是一種不受光照影響的顏色。單獨使用紅色的自發(fā)光:
new THREE.MeshLambertMaterial({ emissive: 0xff0000 })
效果為:
如果同時使用紅色的自發(fā)光與黃色的散射光:
new THREE.MeshLambertMaterial({ color: 0xffff00, emissive: 0xff0000 })
效果為:
球體的效果:
總結(jié)Lamber材質(zhì)的特有屬性:
ambient:設(shè)置材質(zhì)的環(huán)境色,和AmbientLight光源一起使用,這個顏色會與環(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)用于一個球體:
var material = new THREE.MeshPhongMaterial({ specular: 0xff0000 }); var sphere = new THREE.Mesh(new THREE.SphereGeometry(3, 20, 8), material);
效果為:
可以通過shininess屬性控制光照模型中的n值,當(dāng)shininess值越大時,高光的光斑越小,默認(rèn)值為30。我們將其設(shè)置為1000時:
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光源一起使用,這個顏色會與環(huán)境光的顏色相乘。即是對光源作出反應(yīng)。
emissive:設(shè)置材質(zhì)發(fā)射的顏色,不是一種光源,而是一種不受光照影響的顏色。默認(rèn)為黑色
specular:指定該材質(zhì)的光亮程度及其高光部分的顏色,如果設(shè)置成和color屬性相同的顏色,則會得到另一個更加類似金屬的材質(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ì)實例及圖片介紹了Three.js中的Lamber與Phong,希望對大家的學(xué)習(xí)有所幫助,小編會陸續(xù)整理Three.js的相關(guān)文章,對Three.js感興趣的朋友們請繼續(xù)支持腳本之家。
相關(guān)文章
精通JavaScript 糾正 cleanWhitespace函數(shù)
這個函數(shù)用在火狐(firefox)上面老是出錯,今天仔細(xì)研究了下,改正了,希望別人不要遇到我這樣的問題2010-03-03Highcharts學(xué)習(xí)之?dāng)?shù)據(jù)列
數(shù)據(jù)列配置是 Highcharts 最復(fù)雜也是最靈活的配置,如果說 Highcharts 是靈活多變,細(xì)節(jié)可定制的話,那么數(shù)據(jù)列配置就是這個重要特性的核心。2016-08-08Three.js學(xué)習(xí)之Lamber材質(zhì)和Phong材質(zhì)
本篇將介紹基本材質(zhì)以及兩種基于光照模型的材質(zhì)(Lamber與Phong),有需要的小伙伴們可以參考學(xué)習(xí)。2016-08-08Three.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