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 相关文章推荐
网页自动刷新,不产生嗒嗒声的一个解决方法
Mar 27 Javascript
jquery easyui combobox模糊过滤(示例代码)
Nov 30 Javascript
JavaScript实现时间倒计时跳转(推荐)
Jun 28 Javascript
JS解决iframe之间通信和自适应高度的问题
Aug 24 Javascript
详解Angular的内置过滤器和自定义过滤器【推荐】
Dec 26 Javascript
Bootstrap table右键功能实现方法
Feb 20 Javascript
Bootstrap按钮组简单实现代码
Mar 06 Javascript
ES6中数组array新增方法实例总结
Nov 07 Javascript
jQuery easyui datagird编辑行删除行功能的实现代码
Sep 20 jQuery
seajs和requirejs模块化简单案例分析
Aug 26 Javascript
ES6 class类链式继承,实例化及react super(props)原理详解
Feb 15 Javascript
JavaScript JSON使用原理及注意事项
Jul 30 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
Ajax+PHP 边学边练 之二 实例
2009/11/24 PHP
给初学者的30条PHP最佳实践(荒野无灯)
2011/08/02 PHP
Laravel 中获取上一篇和下一篇数据
2015/07/27 PHP
ThinkPHP项目分组配置方法分析
2016/03/23 PHP
PHP实现的DES加密解密类定义与用法示例
2020/11/02 PHP
ExtJS的FieldSet的column列布局
2009/11/20 Javascript
基于JQuery的一句话搞定手风琴菜单
2012/09/14 Javascript
用js格式化金额可设置保留的小数位数
2014/05/09 Javascript
JavaScript中的异常捕捉介绍
2014/12/31 Javascript
jQuery性能优化技巧分析
2015/02/20 Javascript
JavaScript多图片上传案例
2015/09/28 Javascript
js在ie下打开对话窗口的方法小结
2016/10/24 Javascript
利用原生js实现html5小游戏之打砖块(附源码)
2018/01/03 Javascript
vue升级之路之vue-router的使用教程
2018/08/14 Javascript
javascript简单实现深浅拷贝过程详解
2019/10/08 Javascript
vue实现轮播图帧率播放
2021/01/26 Vue.js
Python实现控制台中的进度条功能代码
2017/12/22 Python
Ubuntu下使用python读取doc和docx文档的内容方法
2018/05/08 Python
对Python3 解析html的几种操作方式小结
2019/02/16 Python
Python使用pandas和xlsxwriter读写xlsx文件的方法示例
2019/04/09 Python
python获取微信企业号打卡数据并生成windows计划任务
2019/04/30 Python
python实现两个文件夹的同步
2019/08/29 Python
Python Handler处理器和自定义Opener原理详解
2020/03/05 Python
HTML5+CSS3实例 :canvas 模拟实现电子彩票刮刮乐代码
2016/12/30 HTML / CSS
潘多拉珠宝俄罗斯官方网上商店:PANDORA俄罗斯
2020/09/22 全球购物
PHP如何对用户密码进行加密
2014/07/31 面试题
Linux机考试题
2015/07/17 面试题
英语课前三分钟演讲稿
2014/08/19 职场文书
委托书如何写
2014/08/30 职场文书
大学生军训自我鉴定范文
2014/09/18 职场文书
教师党员个人自我剖析材料
2014/09/29 职场文书
2014年爱国卫生工作总结
2014/11/22 职场文书
师范生见习总结范文
2015/06/23 职场文书
2015年医院保卫科工作总结
2015/07/23 职场文书
MySQL中使用or、in与union all在查询命令下的效率对比
2021/05/26 MySQL
JS前端使用canvas实现扩展物体类和事件派发
2022/08/05 Javascript