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

  本篇将介绍基本材质以及两种基于光照模型的材质(Lamber与Phong)。

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

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

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

1.基本材质

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

THREE.MeshLambertMaterial(opt)

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

new THREE.MeshBasicMaterial({

    color: 0xffff00,

    opacity: 0.75

});

  将其应用于一个正方体(方法参见3.js-4,效果为:

源码:

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

})

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

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

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

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

new THREE.MeshLambertMaterial({

    emissive: 0xff0000

})

  效果为:

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

new THREE.MeshLambertMaterial({

    color: 0xffff00,

    emissive: 0xff0000

})

  效果为:

  球体的效果:

  总结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

});

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

var material = new THREE.MeshPhongMaterial({

    specular: 0xff0000

});

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

  效果为:

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

new THREE.MeshPhongMaterial({

    specular: 0xff0000,

    shininess: 1000

});

  效果为:

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

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入门指南》

  其他参考:THREE.JS中常用的3种材质

Three.js基础探寻七——Lamber材质与Phong材质的更多相关文章

  1. Three.js基础探寻一

    1.webGL 一种网络标准,定义了一些较底层的图形接口. 2.Three.js 一个3Djs库,webGL开源框架中比较优秀的一个.除了webGL以外,Three.js还提供了基于Canvas.SV ...

  2. Three.js基础探寻二——正交投影照相机

    本篇主要介绍照相机中的正交投影照相机. 第一篇传送门:Three.js基础探寻一 1.照相机 图形学中的照相机定义了三维空间到二维屏幕的投影方式. 针对投影方式照相机分为正交投影照相机和透视投影照相机 ...

  3. Three.js基础探寻八——法向材质与材质的纹理贴图

    4.法向材质 法向材质可以将材质的颜色设置为其法向量的方向,有时候对于调试很有帮助. 法向材质的设定很简单,甚至不用设置任何参数: new THREE.MeshNormalMaterial() 材质的 ...

  4. Three.js基础探寻九——网格

    在学习了几何形状和材质之后,我们就能使用他们来创建物体了.最常用的一种物体就是网格(Mesh),网格是由顶点.边.面等组成的物体:其他物体包括线段(Line).骨骼(Bone).粒子系统(Partic ...

  5. Three.js基础探寻四——立方体、平面与球体

    前面简单介绍了webGL和Three.js的背景以及照相机的设定,接下来介绍一些Three.js中的几何形状. 1.立方体 虽然这一形状的名字叫立方体(CubeGeometry),但它其实是长方体,也 ...

  6. Three.js基础探寻六——文字形状与自定义形状

    1.文字形状 说起3d文字想起了早年word里的一些艺术字: 时间真快. 那么TextGeometry可以用来创建三维的文字形状. 使用文字形状需要下载和引用额外的字体库.这里,我们以 helveti ...

  7. Three.js基础探寻十——动画

    本篇将介绍如果使用Three.js进行动态画面的渲染.此外,将会介绍一个Three.js作者写的另外一个库stat.js,用来观测每秒帧数(FPS). 1.实现动画效果 1.1 动画原理 对于Thre ...

  8. js基础第七天

    短信发送验证倒计时案例(常用) 关闭定时器clearInterval this 指向的是 事件的调用者 ,或者是函数的使用者. button 不可以用 disabled 不可用的意思 意思是变成灰色不 ...

  9. Three.js基础探寻三——透视投影照相机

    本篇主要介绍Three.js照相机中的透视投影照相机. 上一篇:正交投影照相机 5.透视投影照相机构造函数 透视投影照相机(Perspective Camera)的构造函数是: THREE.Persp ...

随机推荐

  1. The 14th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple - F 贪心+二分

    Heap Partition Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge A sequence S = { ...

  2. POJ2975:Nim(Nim博弈)

    Nim Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7279   Accepted: 3455 题目链接:http://p ...

  3. 从一个集合中过滤另一个集合中存在的项(类似in)

    直接贴代码出来: List<PriceMark> list = PriceMarkDAL.m_PriceMarkDAL.GetList("Erp_ProName='TLC7528 ...

  4. 报Cannot find /usr/local/tomcat/bin/setclasspath.sh错误

    错误如下: [root@RSP-DEVWEB03 bin]#sh startup.sh Cannot find /usr/local/tomcat8081/bin/setclasspath.sh Th ...

  5. [吴恩达机器学习笔记]14降维5-7重建压缩表示/主成分数量选取/PCA应用误区

    14.降维 觉得有用的话,欢迎一起讨论相互学习~Follow Me 14.5重建压缩表示 Reconstruction from Compressed Representation 使用PCA,可以把 ...

  6. 学习 C++的用途,(前辈总结)

    C++准确说是一门中级语言,介于汇编和高级语言之间吧,要求程序员了解计算机的内部数据存储.个人认为,作为学生还是花功夫学C++,因为<设计模式><数据结构>这些课程基本上还是C ...

  7. sublime wrong

    Q1: sublime报错: There are no packages available for installation A1: window下的:C:\Windows\System32\dri ...

  8. POJ 3304 Segments 基础线段交判断

    LINK 题意:询问是否存在直线,使得所有线段在其上的投影拥有公共点 思路:如果投影拥有公共区域,那么从投影的公共区域作垂线,显然能够与所有线段相交,那么题目转换为询问是否存在直线与所有线段相交.判断 ...

  9. 816B. Karen and Coffee 前缀和思维 或 线段树

    LINK 题意:给出n个[l,r],q个询问a,b,问被包含于[a,b]且这样的区间数大于k个的方案数有多少 思路:预处理所有的区间,对于一个区间我们标记其(左边界)++,(右边界+1)--这样就能通 ...

  10. Unsupervised learning, attention, and other mysteries

    Unsupervised learning, attention, and other mysteries Get notified when our free report “Future of M ...