Three.js学习之Lamber材质和Phong材质


Posted in Javascript onAugust 04, 2016

前言

材质(Material)是独立于物体顶点信息之外的与渲染效果相关的属性。通过设置材质可以改变物体的颜色、纹理贴图、光照模式等。

MeshBasicMaterial:对光照无感,给几何体一种简单的颜色或显示线框。

MeshLambertMaterial:这种材质对光照有反应,用于创建暗淡的不发光的物体。

MeshPhongMaterial:这种材质对光照也有反应,用于创建金属类明亮的物体。

1.基本材质

使用基本材质(BasicMaterial)的物体,渲染后物体的颜色始终为该材质的颜色,而不会由于光照产生明暗、阴影效果。如果没有指定材质的颜色,则颜色是随机的。其构造函数是:

THREE.MeshLambertMaterial(opt)

其中,opt可以缺省,或者为包含各属性的值。如新建一个不透明度为0.75的黄色材质:

new THREE.MeshBasicMaterial({

 color: 0xffff00,

 opacity: 0.75

});

将其应用于一个正方体(方法参见《Three.js学习之几何形状》,效果为:

Three.js学习之Lamber材质和Phong材质

源码:

<!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:是否可见,默认为true

· side:渲染面片正面或是反面,默认为正面THREE.FrontSide,可设置为反面THREE.BackSide,或双面THREE.DoubleSide

· wireframe:是否渲染线而非面,默认为false

· color:十六进制RGB颜色,如红色表示为0xff0000

· map:使用纹理贴图 

对于基本材质,即使改变场景中的光源,使用该材质的物体也始终为颜色处处相同的效果。当然,这不是很具有真实感,因此,接下来我们将介绍更为真实的光照模型:Lambert光照模型以及Phong光照模型。 

2.Lamber材质与Phong材质

Lambert材质(MeshLambertMaterial)是符合Lambert光照模型的材质。Lambert光照模型的主要特点是只考虑漫反射而不考虑镜面反射的效果,因而对于金属、镜子等需要镜面反射效果的物体就不适应,对于其他大部分物体的漫反射效果都是适用的。

其光照模型公式为:

Idiffuse = Kd * Id * cos(theta)

其中,Idiffuse是漫反射光强,Kd是物体表面的漫反射属性,Id是光强,theta是光的入射角弧度。

当然,对于使用Three.js的Lambert材质,不需要了解以上公式就可以直接使用。

创建一个黄色的Lambert材质的方法为:

new THREE.MeshLambertMaterial({

 color: 0xffff00

})

在使用了光照之后,得到这样的效果:

 Three.js学习之Lamber材质和Phong材质

color是用来表现材质对散射光的反射能力,也是最常用来设置材质颜色的属性。除此之外,还可以用ambient和emissive控制材质的颜色。

ambient表示对环境光的反射能力,只有当设置了AmbientLight后,该值才是有效的,材质对环境光的反射能力与环境光强相乘后得到材质实际表现的颜色。

emissive是材质的自发光颜色,可以用来表现光源的颜色,并不是一种光源,而是一种不受光照影响的颜色。单独使用红色的自发光:

new THREE.MeshLambertMaterial({

 emissive: 0xff0000

})

效果为:

 Three.js学习之Lamber材质和Phong材质

如果同时使用红色的自发光与黄色的散射光:

new THREE.MeshLambertMaterial({

 color: 0xffff00,

 emissive: 0xff0000

})

效果为:

 Three.js学习之Lamber材质和Phong材质

球体的效果:

 Three.js学习之Lamber材质和Phong材质

   总结Lamber材质的特有属性:

ambient:设置材质的环境色,和AmbientLight光源一起使用,这个颜色会与环境光的颜色相乘。即是对光源作出反应。

emissive:设置材质发射的颜色,不是一种光源,而是一种不受光照影响的颜色。默认为黑色。 

  源码: 

<!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材质

Phong材质(MeshPhongMaterial)是符合Phong光照模型的材质。和Lambert不同的是,Phong模型考虑了镜面反射的效果,因此对于金属、镜面的表现尤为适合。

漫反射部分和Lambert光照模型是相同的,镜面反射部分的模型为:

        Ispecular = Ks * Is * (cos(alpha)) ^ n

其中,Ispecular是镜面反射的光强,Ks是材质表面镜面反射系数,Is是光源强度,alpha是反射光与视线的夹角,n是高光指数,越大则高光光斑越小。

由于漫反射部分与Lambert模型是一致的,因此,如果不指定镜面反射系数,而只设定漫反射,其效果与Lambert是相同的:

new THREE.MeshPhongMaterial({

 color: 0xffff00

});

Three.js学习之Lamber材质和Phong材质

同样地,可以指定emissive和ambient值,这里不再说明。下面就specular值指定镜面反射系数作说明。首先,我们只使用镜面反射,将高光设为红色,应用于一个球体:

var material = new THREE.MeshPhongMaterial({

 specular: 0xff0000

});

var sphere = new THREE.Mesh(new THREE.SphereGeometry(3, 20, 8), material);

效果为:

 Three.js学习之Lamber材质和Phong材质

可以通过shininess属性控制光照模型中的n值,当shininess值越大时,高光的光斑越小,默认值为30。我们将其设置为1000时:

new THREE.MeshPhongMaterial({

 specular: 0xff0000,

 shininess: 1000

});

效果为:

 Three.js学习之Lamber材质和Phong材质

使用黄色的镜面光,红色的散射光:

material = new THREE.MeshPhongMaterial({

 color: 0xff0000,

 specular: 0xffff00,
 
 shininess: 100

});

总结Phong材质的特有属性:

ambient:设置材质的环境色,和AmbientLight光源一起使用,这个颜色会与环境光的颜色相乘。即是对光源作出反应。

emissive:设置材质发射的颜色,不是一种光源,而是一种不受光照影响的颜色。默认为黑色

specular:指定该材质的光亮程度及其高光部分的颜色,如果设置成和color属性相同的颜色,则会得到另一个更加类似金属的材质,如果设置成grey灰色,则看起来像塑料

shininess:指定高光部分的亮度,默认值为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>

总结

本文的内容到这就结束了,文章通过详细实例及图片介绍了Three.js中的Lamber与Phong,希望对大家的学习有所帮助,小编会陆续整理Three.js的相关文章,对Three.js感兴趣的朋友们请继续支持三水点靠木。

Javascript 相关文章推荐
基于jquery的3d效果实现代码
Mar 23 Javascript
判断js对象是否拥有某一个属性的js代码
Aug 16 Javascript
jQuery设置与获取HTML,文本和值的简单实例
Feb 26 Javascript
JQuery为页面Dom元素绑定事件及解除绑定方法
Apr 23 Javascript
jQuery实现输入框下拉列表树插件特效代码分享
Aug 27 Javascript
JS操作XML实例总结(加载与解析XML文件、字符串)
Dec 08 Javascript
浅谈jQuery框架Ajax常用选项
Jul 08 jQuery
vue实现登陆登出的实现示例
Sep 15 Javascript
关于AngularJS中ng-repeat不更新视图的解决方法
Sep 30 Javascript
解决layui 三级联动下拉框更新时回显的问题
Sep 03 Javascript
vue父子组件间引用之$parent、$children
May 20 Javascript
一起深入理解js中的事件对象
Feb 06 Javascript
基于JavaScript实现在新的tab页打开url
Aug 04 #Javascript
同步文本框内容JS代码实现
Aug 04 #Javascript
JS打印组合功能
Aug 04 #Javascript
Listloading.js移动端上拉下拉刷新组件
Aug 04 #Javascript
jQuery选择器总结之常用元素查找方法
Aug 04 #Javascript
Bootstrap中表单控件状态(验证状态)
Aug 04 #Javascript
Bootstrap实现input控件失去焦点时验证
Aug 04 #Javascript
You might like
php实现无限级分类实现代码(递归方法)
2011/01/01 PHP
Window下PHP三种运行方式图文详解
2013/06/11 PHP
PHP内置加密函数详解
2016/11/20 PHP
PHP静态成员变量和非静态成员变量详解
2017/02/14 PHP
Add a Formatted Table to a Word Document
2007/06/15 Javascript
基于jquery.Jcrop的头像编辑器
2010/03/01 Javascript
LazyLoad 延迟加载(按需加载)
2010/05/31 Javascript
JavaScript判断变量是否为undefined的两种写法区别
2013/12/04 Javascript
让alert不出现弹窗的两种方法
2014/05/18 Javascript
Jquery实现纵向横向菜单
2016/01/24 Javascript
jQuery实现倒计时重新发送短信验证码功能示例
2017/01/12 Javascript
jQuery实现可编辑表格并生成json结果(实例代码)
2017/07/19 jQuery
详解在React中跨组件分发状态的三种方法
2018/08/09 Javascript
微信小程序导入Vant报错VM292:1 thirdScriptError的解决方法
2019/08/01 Javascript
搭建vscode+vue环境的详细教程
2020/08/31 Javascript
python smtplib模块发送SSL/TLS安全邮件实例
2015/04/08 Python
opencv python统计及绘制直方图的方法
2019/01/21 Python
新年快乐! python实现绚烂的烟花绽放效果
2019/01/30 Python
pandas 时间格式转换的实现
2019/07/06 Python
使用python telnetlib批量备份交换机配置的方法
2019/07/25 Python
Django接收post前端返回的json格式数据代码实现
2019/07/31 Python
Python pandas用法最全整理
2019/08/04 Python
CSS3 transition 实现通知消息轮播条
2020/10/14 HTML / CSS
html5唤醒APP小记
2019/03/27 HTML / CSS
澳大利亚旅游网站:Lastminute
2017/08/07 全球购物
幼教个人求职信范文
2013/12/02 职场文书
人事行政主管岗位职责
2013/12/22 职场文书
《动手做做看》教学反思
2014/04/09 职场文书
工商局所长四风自我剖析及整改措施
2014/10/26 职场文书
中秋节慰问信
2015/02/15 职场文书
党员评议自我评价
2015/03/03 职场文书
终止解除劳动合同证明书
2015/06/17 职场文书
教师个人工作总结范文2015
2015/10/14 职场文书
2016党员干部政治学习心得体会
2016/01/23 职场文书
导游词之无锡梅园
2019/11/28 职场文书
MySQL CHAR和VARCHAR该如何选择
2021/05/31 MySQL