09.Three.js 基础之材质
09 Three.js 基础之材质
材质
按照用途,所以材质大体上可以划分为:
- 点材质
( 应用来点、粒子上) - 线性材质
( 应用在线段或虚线上) - 基础材质
( 应用在面上的各种材质) - 特殊用途的材质
( 例如阴影) - 自定义材质
上面的分类划分,仅仅是我个人观点,事实上并没有明确的种类划分规定。
材质基础
材质名称 | 解释说明 |
---|---|
Material | 所有材质的父类 |
点材质
材质名称 | 解释说明 |
---|---|
PointsMaterial | 点材质 |
线性材质
材质名称 | 解释说明 |
---|---|
LineBasicMaterial | 线段材质 |
LineDashedMaterial | 虚线材质 |
基础材质( 针对”面“)
材质名称 | 解释说明 |
---|---|
MeshBasicMaterial | 最基础的材质,不反射光,仅显示材质本身颜色 |
MeshLambertMaterial | 仅顶点处反射光 |
MeshMatcapMaterial | 自带光效 |
MeshPhongMaterial | 任何点都反射光,拥有光泽度 |
MeshToonMaterial | 卡通着色 |
MeshStandardMaterial | 除光泽度外,还有粗糙度和金属度 |
MeshPhysicalMaterial | 除光泽度、粗糙度、金属度外,还有清漆度和清漆粗糙度 |
特殊用途材质
材质名称 | 解释说明 |
---|---|
ShadowMaterial | 阴影材质 |
MeshDistanceMaterial | 另外一种阴影投射材质 |
MeshDeptMaterial | 远近距离深度着色材质 |
MeshNormalMaterial | 网格法向量材质 |
SpriteMaterial | 精灵材质 |
自定义材质
材质名称 | 解释说明 |
---|---|
ShaderMaterial | 着色器材质 |
RawShaderMaterial | 原始着色器材质 |
注意:本文只是大体上讲解一些
点材质:PointsMaterial
PointsMaterial:点材质/ 粒子材质
用来创建 粒子 材质。
线性材质:LineBasicMaterial、LineDashedMaterial
LineBasicMaterial:基础的线段材质
用来创建 线段 的材质,属性包括:颜色、宽度、断点、连接点等。
LineDashedMaterial:虚线材质
基础材质讲解说明
为什么要先讲MeshPhongMaterial ?
因为
- 比
MeshPhongMaterial 简单的有MeshBasicMaterial 、MeshLambertMaterial - 和
MeshPhongMaterial 相似的有MeshToonMaterial - 比
MeshPhongMaterial 复杂的有MeshStandardMaterial 、MeshPhysicalMaterial
MeshPhongMaterial
Phong 光照模型:
Phong 的假设前提:
- 物体通常被设置为不透明
- 物体表面反射率相同
Phone 的简单用法:
新建一个
const material = new Three.MeshPhongMaterial({
color:0xFF0000,
flatShading:true
})
或者
const material = new Three.MeshPhoneMaterial()
material.color.set(0xFF0000)
material.flatShading = true
设置颜色的
new Three.MeshPhoneMaterial({color:0xFF0000})
new Three.MeshPhoneMaterial({color:'red'})
new Three.MeshPhoneMaterial({color:'#F00'})
new Three.MeshPhoneMaterial({color:'rgb(255,0,0)'})
new Three.MeshPhoneMaterial({color:'hsl(0,100%,50%)'})
修改颜色:
material.color.set(0xFF0000)
material.color.set('red')
material.color.set('#F00')
material.color.set('rgb(255,0,0)')
material.color.set('hsl(0,100%,50%)')
material.color.setHSL(0,1,0.5)
material.color.setRGB(1,0,0)
Phong 的属性:flatShading( 平面着色)
特别强调:
只不过由于
默认值为
false ,即不启用 平面着色 模式。
补充说明3 大着色模式:
什么叫 着色?
在三维图形学中
这个 “着色” 过程中,就牵扯到不同的着色算法,也就是不同的着色模式。
最常见的3 种着色算法( 模式) :
Flat Shading:平面着色
根据每个三角形的法线计算着色效果,每个面只计算一次,也就是说相同的面采用同一个计算结果。
这种模式对于 立方体 来说会减小计算量,因为立方体每个面都是平整且唯一的。
Gouraud Shading:逐顶着色
针对每个顶点计算,而后对每个顶点的结果颜色进行线性插值得到片源的颜色。
Phong Shading:补色渲染
对每个三角形的每个片元进行着色计算。所以
由于颜色是按片元着色的,得到的结果比 逐顶着色
所以
以下内容更新于
2022.02.02
在图形学中有一个被应用非常广泛的简单光照模型:冯氏光照模型
注:这里的 简单 是指计算量非常小,但却可以模拟出简单的高光和漫反射。
冯氏光照模型、冯氏着色法 简介:
裴祥风
冯氏光照模型主要有
-
环境光照
(Ambient Lighting) :物体几乎永远不会是完全黑暗的,环境光照一般是一个常量。 -
漫反射光照
(Diffuse Lighting) :模拟光源对物体的方向性影响,越是正对着光源的地方越亮。通过计算物体平面某个点的法向量与该点与光源的单位向量进行乘积,得到该点的亮度。
当这两个向量相互重叠时该点最亮
( 亮度值为1) ,当这两个向量成九十度则最暗( 亮度值为0) 向量、法线、乘积
( 也称内积) 这些都是 线性代数 中的词语,属于图形学中需要掌握的基础知识。如果学会了基础的Three.js 后一定要去学习图形学,否则以后也做不出什么好的应用。 -
镜面光照
(Specular Lighting) :模拟有光泽物体上面出现的亮点。
最终物体呈现的样子就是以上
冯氏着色法
与冯氏着色法相对的有:平面着色法
以上内容更新于
2022.02.02
Phong 光照反射模型 也被称为 冯氏反射模型
特别补充:
MeshPhongMaterial 中的Phong 是指Phong 光照反射模型Phong Shading 中的Phong 只指 补色渲染Phong 光照反射模型、Phong 补色渲染 这2 个理论都是由 科学家Bui Tuong Phong 提出的,所以也都以他的名字命名。
目前来说,补色渲染
Phong 的属性:emissive( 发光颜色)
注意:若将材质的
Phong 的属性:shininess( 光泽度)
- 最小值可设置为
0 ,即无光泽度,此时呈现出的效果和Lambert 相同 - 默认值为
30 - 该值越大,光泽度越高,呈现的效果越接近 高清玻璃或钢琴烤漆的那种光泽感
注意:若将材质的
MeshBasicMaterial、MeshLambertMaterial
当我们对
几种材质的光感对比:
-
MeshBasicMaterial:不反射任何光,仅显示材质本身颜色
-
MeshLambertMaterial:仅顶点处反射光
-
MeshPhongMaterial:任何地方都可反射光
Lambert 虽然顶点也可以反光,但是相对Phong 而言,Lambert 整体反光度极其微小、不明显
性能提示:
关于颜色,以下
- 基于
MeshBasicMaterial ,color 设置为紫色 - 基于
MeshLambertMaterial ,color 设置为黑色,emissive 设置为 紫色 - 基于
MeshPhongMaterial ,color 设置为黑色,emissive 设置为 紫色,shininess 设置为0
以上
但是,从渲染性能上来讲,从上往下 所需要的性能越来越高,因此假设材质不需要
MeshToonMaterial
注意
: “渐变贴图( X 乘1 的纹理) " 这句话我是从参考教程中看到的,我并没理解这句话的含义。
并不是说必须要设置纹理图片,若不设置则会采用默认的渐变策略:
- 前
70% 区域 亮度为70% - 后
30% 区域亮度为100%
最终呈现出的效果,看起来特别像卡通动画的风格。所以
卡通动画通常大面积为纯色,只在底部增加深色的颜色,以此来表现出立体效果。
补充一点:
网上很多教程在讲解
“MeshToonMaterial 是 MeshPhongMaterial 的扩展”
但是我自己通过
MeshMatcapMaterial
一种自带光效
MeshStandardMaterial、MeshPhysicalMaterial
- roughness:粗糙度,取值范围为
0 - 1 ,即0 为粗糙度最低,此时表现出的光泽度最高 - metalness:金属度,取值范围为
0 - 1 ,即0 为非金属、金属度最高为1
在 粗糙度和金属度 共同的作用下,呈现出 更加细腻、可控 的光泽度。
- clearcoat:添加
( 应用) 透明涂层的程度,取值范围为0 - 1 - clearCoatRoughness:透明涂层的粗糙度,取值范围为
0 - 1
额外添加的透明涂层,在装修上有一个专业的名词:清漆
清漆 会让物体呈现出更加光泽的效果。
因此:
clearcoat 可以翻译成:添加 清漆 的程度clearCoatRoughness 翻译成:清漆粗糙度
基础材质小总结
从各种材质渲染所需性能,也就是渲染所需时间的快慢排序,依次是:
MeshBasicMaterial > MeshLambertMaterial > MeshPhongMaterial > MeshStandardMaterial > MeshPhysicalMaterial
上面排序中,越靠后的材质所呈现出的 细节 越多、真实感越强。
特殊材质:ShadowMaterial、MeshDistanceMaterial、MeshDepthMaterial、MeshNormalMaterial
ShadowMaterial:阴影类型的材质
我们目前还从未在示例中使用过
MeshDistanceMaterial:另外一种阴影投射材质
相对于
MeshDepthMaterial:以像素的深度来着色的材质
当物体距离镜头越近时会呈现白色、当距离越远时会呈现黑色。
你可以想象成在黑夜中去看远方的发光物体,越近的物体所发出的光眼睛看到的越多
( 显得物体越亮) ,越远的物体所发出的光越暗,直至完全消失在黑暗中。
创建镜头的时候,会有
2 个 参数:near( 最近距离) 、far( 最远距离)
MeshNormalMaterial:网格法向量材质
该材质是根据 三角面 的 法向量 方向的不同,从而赋予不同的颜色。
当物体旋转的时候由于各个面的法向量不断发生变化,物体的颜色也是不断发生变化。
SpriteMaterial:精灵材质/ 雪碧材质
精灵材质,也叫 雪碧材质。
大体来说,就是在场景中,可以加载图片,并且将图片当做纹理贴图,使用在材质上。
自定义材质:ShaderMaterial、RawShaderMaterial
ShaderMaterial:使用Three.js 着色器制作自定义材质
RawShaderMaterial:完全自定义着色器所创建的自定义材质
特殊材质、自定义材质具体的用法,此刻都不必深究,道路漫漫,时间还长,以后再慢慢研究。
材质通用、常用的2 个属性:flatShading、side
flatShading:是否平面着色
默认值为
若设置值为
若启用平面着色,会让物体看起来更像是多面体,而不是光滑体。
本文在讲解
MeshPhongMaterial 的时候已经提到过此属性。
side:显示三角形的哪侧边( 面)
默认值为
若设置值为
对于绝大多数 图元 来说,通常 内部是不可见的,例如 球体或立方体的内部 你是看不见的,只能看见外面。
side 通常是针对平面或非实体对象才有效果,例如 一个平面圆形,则背对 镜头的那一面即内面,在物体旋转过程中是可以看到内测那一面的。
若设置值为
对于实体物体对象
( 非平面物体) 设置值为Three.BackSide 或Three.DoubleSide 都是无意义的。
材质不常用的1 个属性:needsUpdate
第1 种情况:材质种类发生了重大变化
针对 面 的材质,之前已经提到过,大致分文
在实际项目中,通常情况下我们并不会将某个物体的材质进行
例如我们不太会将某个 物体的材质 由某种基础材质突然变更为 阴影材质。
尽管实际中发生几率非常小,但万一要发生了呢?
第2 种情况:材质种类没变,但设置发生了变化
若材质在被使用过后,发生了以下
flatShading 属性值的改变- 添加或删除 纹理
(texture) - 从不使用纹理变为使用纹理
- 从使用纹理变为不使用纹理
- 纹理的变更是允许的,并不属于 “添加或删除纹理” 的范畴中
设置needsUpdate 属性
当上述
material.needsUpdate = true
明确告知
更换新的材质并重新渲染,这个过程将消耗比较多的计算性能。
补充说明:
在官方教程中,讲解
在从纹理过渡到无纹理的情况下,通常最好使用1x1像素的白色纹理。
由于目前还没有学习过纹理,所以我暂时没理解这句话具体的含义是什么。
关于 材质 的一些基础知识,本文已经讲完。
具体的每个材质都需要阅读官方文档,以及经过大量的练习才能掌握。
同一个材质在不同光照、纹理的作用下,可能呈现出的效果相差很大。
下一节,学习 纹理