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 25 Javascript
JS 新增Cookie 取cookie值 删除cookie 举例详解
Oct 10 Javascript
js父页面与子页面不同时显示的方法
Oct 16 Javascript
jQuery验证元素是否为空的两种常用方法
Mar 17 Javascript
JavaScript代码性能优化总结篇
May 15 Javascript
完美解决js传递参数中加号和&amp;号自动改变的方法
Oct 11 Javascript
Vue.js 60分钟快速入门教程
Mar 28 Javascript
详解Angular系列之变化检测(Change Detection)
Feb 26 Javascript
vue3.0 CLI - 2.6 - 组件的复用入门教程
Sep 14 Javascript
js实现转动骰子模型
Oct 24 Javascript
VueJS实现用户管理系统
May 29 Javascript
vue本地构建热更新卡顿的问题“75 advanced module optimization”完美解决方案
Aug 05 Vue.js
基于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
浅谈Windows下 PHP4.0与oracle 8的连接设置
2006/10/09 PHP
检查用户名是否已在mysql中存在的php写法
2014/01/20 PHP
php去除字符串换行符示例分享
2014/02/13 PHP
PHP简单获取网站百度搜索和搜狗搜索收录量的方法
2016/08/23 PHP
laravel5.1 ajax post 传值_token示例
2019/10/24 PHP
Javascript 中介者模式实例
2009/12/16 Javascript
jQuery使用技巧简单汇总
2013/04/18 Javascript
jQuery 关于伪类选择符的使用说明
2013/04/24 Javascript
jquery.post用法示例代码
2014/01/03 Javascript
node.js使用require()函数加载模块
2014/11/26 Javascript
浅谈jQuery中setInterval()方法
2015/07/07 Javascript
理解 JavaScript Scoping &amp; Hoisting(二)
2015/11/18 Javascript
JS实现的倒计时效果实例(2则实例)
2015/12/23 Javascript
JavaScript+html5 canvas绘制渐变区域完整实例
2016/01/26 Javascript
JS失效 提示HTML1114: (UNICODE 字节顺序标记)的代码页 utf-8 覆盖(META 标记)的冲突的代码页 utf-8
2017/06/23 Javascript
vuejs手把手教你写一个完整的购物车实例代码
2017/07/06 Javascript
在vue里面设置全局变量或数据的方法
2018/03/09 Javascript
jQuery获取随机颜色的实例代码
2018/05/21 jQuery
使用Vue开发自己的Chrome扩展程序过程详解
2019/06/21 Javascript
jQuery位置选择器用法实例分析
2019/06/28 jQuery
vue中选中多个选项并且改变选中的样式的实例代码
2020/09/16 Javascript
python通过cookie模拟已登录状态的初步研究
2016/11/09 Python
python自动登录12306并自动点击验证码完成登录的实现源代码
2018/04/25 Python
python3实现名片管理系统
2020/11/29 Python
通过代码实例了解Python sys模块
2020/09/14 Python
Python可视化工具如何实现动态图表
2020/10/23 Python
python爬取代理ip的示例
2020/12/18 Python
浙大网新C/C++面试解惑
2015/05/27 面试题
高中生的自我鉴定范文
2014/01/24 职场文书
求职者怎样写自荐信
2014/04/13 职场文书
应届生找工作求职信
2014/06/24 职场文书
2016年度先进班组事迹材料
2016/03/01 职场文书
廉洁自律承诺书2016
2016/03/25 职场文书
合同范本之电脑出租
2019/08/13 职场文书
python 提取html文本的方法
2021/05/20 Python
如何使用PostgreSQL进行中文全文检索
2021/05/27 PostgreSQL