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 相关文章推荐
JavaScript 组件之旅(二)编码实现和算法
Oct 28 Javascript
JavaScript Distilled 基础知识与函数
Apr 07 Javascript
JavaScript Chart 插件整理
Jun 18 Javascript
js操作时间(年-月-日 时-分-秒 星期几)
Jun 20 Javascript
js调用浏览器打印模块实现点击按钮触发自定义函数
Mar 21 Javascript
js读取json的两种常用方法示例介绍
Oct 19 Javascript
jquery实现左右无缝轮播图
Jul 31 Javascript
javascript创建含数字字母的随机字符串方法总结
Aug 01 Javascript
基于AngularJS前端云组件最佳实践
Oct 20 Javascript
jQuery的中 is(':visible') 解析及用法(必看)
Feb 12 Javascript
AngularJS 教程及实例代码
Oct 23 Javascript
vue 中Virtual Dom被创建的方法
Apr 15 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
福利彩票幸运号码自动生成器
2006/10/09 PHP
php Static关键字实用方法
2010/06/04 PHP
一个PHP缓存类代码(附详细说明)
2011/06/09 PHP
php网上商城购物车设计代码分享
2012/02/15 PHP
PHP中的session安全吗?
2016/01/22 PHP
Zend Framework路由器用法实例详解
2016/12/11 PHP
php 中phar包的使用教程详解
2018/10/26 PHP
一些Javascript的IE和Firefox(火狐)兼容性的问题总结及常用例子
2009/05/21 Javascript
jQuery控制输入框只能输入数值的小例子
2013/03/20 Javascript
使用JS读秒使用示例
2013/09/21 Javascript
jquery ajax,ashx,json的用法总结
2014/02/12 Javascript
自己实现ajax封装示例分享
2014/04/01 Javascript
JavaScript电子时钟倒计时第二款
2016/01/10 Javascript
JavaScript实现解析INI文件内容的方法
2016/11/17 Javascript
js 定位到某个锚点的方法
2016/11/19 Javascript
详解Vue结合后台的列表增删改案例
2018/08/21 Javascript
python求解水仙花数的方法
2015/05/11 Python
可能是最全面的 Python 字符串拼接总结【收藏】
2018/07/09 Python
用python实现k近邻算法的示例代码
2018/09/06 Python
postman模拟访问具有Session的post请求方法
2019/07/15 Python
python实现一行输入多个值和一行输出多个值的例子
2019/07/16 Python
用python中的matplotlib绘制方程图像代码
2019/11/21 Python
简单了解Python3 bytes和str类型的区别和联系
2019/12/19 Python
python模拟哔哩哔哩滑块登入验证的实现
2020/04/24 Python
荷兰照明、灯具和配件网上商店:dmlights
2019/08/25 全球购物
linux下进程间通信的方式
2014/12/23 面试题
日语专业推荐信
2013/11/12 职场文书
市场营销专业个人求职信范文
2013/12/14 职场文书
12月小学生校园广播稿
2014/02/04 职场文书
七一建党节演讲稿
2014/09/11 职场文书
2015年七一建党节演讲稿
2015/03/19 职场文书
前台接待员岗位职责
2015/04/15 职场文书
新闻通讯稿范文
2015/07/22 职场文书
python自动统计zabbix系统监控覆盖率的示例代码
2021/04/03 Python
浅谈python数据类型及其操作
2021/05/25 Python
CSS使用伪类控制边框长度的方法
2022/01/18 HTML / CSS