# 一、纹理

3D TEXTURES | Free seamless PBR textures with Diffuse, Normal, Displacement, Occlusion and Roughness Maps.(纹理材质)

# 1. 加载并使用纹理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// const TextureLoader = new THREE.TextureLoader() //创建纹理加载器
//加载纹理有三个回调函数,第一个是加载完成后调用,第二个是处于进程中调用,第三个是出现错误后调用
// const texture = TextureLoader.load('./wood/Door_Wood_001_basecolor.jpg',()=>{renderer.render(scene, camera)},()=>{},()=>{})

//引入进程管理,当要加载多个纹理的时候可以使用loadingManager管理进程。
const loadingManager = new THREE.LoadingManager()
const textureLoader = new THREE.TextureLoader(loadingManager)
const texture = textureLoader.load('./wood/Door_Wood_001_basecolor.jpg')
loadingManager.onStart=()=>{

}//开始加载触发
loadingManager.onProgress=()=>{

}//处于进程时触发
loadingManager.onLoad=()=>{
renderer.render(scene, camera)
}//加载完成后触发
loadingManager.onError=()=>{
console.log('error')
}//错误时触发

texture.repeat.x = 3 //x轴上重复的次数
texture.repeat.y = 4 //y轴上重复的次数
//如果不设置以下属性的话,只会是像素的拉伸。
texture.wrapS = THREE.RepeatWrapping
texture.wrapT = THREE.RepeatWrapping
//设置偏移
texture.offset.x = 1
texture.offset.y = 2
//设置旋转,注意使用弧度制
texture.rotation = Math.PI
//纹理扩大或者缩小
//当纹理大于物体的大小时,选择以何种方式缩小,这点在学习webgl的时候就了解过了。
texture.minFilter = THREE.NearestFilter
texture.magFilter = THREE.NearestFilter

# 2. 纹理类型

  1. colorTexture:基础纹理,用于给物体增加颜色。
  2. alphaTexture:一张灰度图,白色代表完全不透明,黑色代表透明。越灰越透明
  3. heightTexture:同样是一张灰度图,白色代表最高点,黑色代表最低点,越灰越低。以此创建凹凸不平的感觉。
  4. normalTexture:法线纹理,用于记录纹理每个面的法线位置。用于得到更好的光影效果。其中使用 x 表示红色,y 表示绿色,z 表示蓝色。就可以将法线的方向用颜色表示。
  5. ambientOcclusionTexture:环境遮挡纹理,用于模拟光线在物体表面缝隙和凹凸部分的衰减和阴影效果的技术。同时也是灰度图,白色为完全遮挡,黑色为完全没遮挡
  6. metalnessTexture:金属纹理,同样也是灰度图,黑色为非金属,白色为金属。
  7. roughnessTexture:描述物体粗糙程度的纹理。

# 二、材质

​ 以下材质继承至父类 Material,拥有父类的一些方法和属性

​ color: 设置颜色
​ map: 纹理,如果设置了纹理同时又设置了颜色,则会融合

​ opacity: 不透明度,默认为 1,0 为完全透明
​ transparent: 指定材质是否透明,默认为 false
​ side: 指定物体的渲染面。有三个值分别是 THREE.FrontSide (默认值,只渲染前面),THREE.BackSide (只渲染背面),THREE.DoubleSide (双面都渲染)

​ 参考资料

Material – three.js docs (threejs.org)

# 1. MeshBasicMaterial

​ 这种材质不受光照影响,为基础材质。

1
2
3
4
5
const material = new THREE.MeshBasicMaterial({
envmMap: 环境纹理,默认是null
lightMap: 光照纹理,默认是null
lightMapIntensity: 烘焙光的强度。
})

# 2. MeshNormalMaterial

​ 法线材质,使用该材质,会获取物体每个面上的法向量,将 rgb 用 xyz 表示获得该面的颜色

1
2
3
const material = new THREE.MeshNormalMaterial({
normalMap: 法线纹理
})

# 3. MeshMatcapMaterial

​ 该材质为物体接受光照照射后渲染而成的,所以与 MeshBasicMaterial 一样不受光照影响。给物体赋予此材质可以模拟光照效果。

1
2
3
4
5
const material = new THREE.MeshMatcapMaterial({
normalMap: 法线纹理
bumpMap; 凹凸纹理,如果设置了法线纹理则忽略该属性
matcap: matcap纹理
})

# 4. MeshDepthmaterial

​ 该材质靠近时为白色,离远些就是黑色。

1
const material = new THREE.MeshDepthmaterial()

# 5.MeshLamberMaterial

​ 使用 Blinn-Phong 模型的材质有两个分别是 MeshLamberMaterial,MeshPhongMaterial。 漫反射材质。如果不设置光照的话,就无法显示,能与光照产生反应,但是无法产生镜面反射,只有漫反射。

1
2
3
4
5
6
7
8
const material = new THREE.MehLamberMaterial({
normalMap: 法线纹理
bumpMap; 凹凸纹理,如果设置了法线纹理则忽略该属性
envmMap: 环境纹理,默认是null
lightMap: 光照纹理,默认是null
lightMapIntensity: 烘焙光的强度。
specularMap : 高光贴图
})

# 6.MeshPhongMaterial

​ 高光材质。该材质使用 Blinn-Phong 模型计算发射率,相比 MeshLamberMaterial 多了镜面反射。

1
2
3
4
5
6
7
8
9
10
const material = new THREE.MeshPhongMaterial({
normalMap: 法线纹理
bumpMap; 凹凸纹理,如果设置了法线纹理则忽略该属性
envmMap: 环境纹理,默认是null
lightMap: 光照纹理,默认是null
lightMapIntensity: 烘焙光的强度。
specularMap : 高光贴图
shininess: 高亮程度,值越高越亮,默认为30
soecular : 高光的颜色,默认为0x111111(深灰色)
})

# 7. MeshToonMaterial

一种卡通的材质。

1
2
3
4
5
6
const material = new THREE.MeshToonMaterial({
normalMap: 法线纹理
bumpMap; 凹凸纹理,如果设置了法线纹理则忽略该属性
emissiveMap: 发光贴图
gradientMap: 渐变纹理,设置此纹理的时候Texture.minFilter和Texture.magFilter设置成THREE.NearestFilter.
})

# 8.MeshStandardMaterial

​ 基于物理的渲染 (physically-based rendering) 渲染的材料有两个,一个是 MeshStandardMaterial,另一个是 MeshPhysicalMaterial。pbr 相对于 Blinn-Phong 光照模型有更加逼真的效果,代价是更加耗费性能。

1
2
3
4
5
6
7
8
9
10
const material = new THREE.MeshPhongMaterial({
normalMap: 法线纹理
bumpMap; 凹凸纹理,如果设置了法线纹理则忽略该属性
envmMap: 环境纹理,默认是null
lightMap: 光照纹理,默认是null
lightMapIntensity: 烘焙光的强度。
refractionRatio:空气折射率除以材质折射率,默认为0.98
roughness:材质粗糙程度
roghnessMap:粗糙纹理
})

# 9.MeshPhysicalMaterial

​ 相比 MeshStandardMaterial 提供更高级的基于物理渲染的属性。

  • Clearcoat: 有些类似于车漆,碳纤,被水打湿的表面的材质需要在面上再增加一个透明的,具有一定反光特性的面。而且这个面说不定有一定的起伏与粗糙度。Clearcoat 可以在不需要重新创建一个透明的面的情况下做到类似的效果。
  • 基于物理的透明度:.opacity 属性有一些限制:在透明度比较高的时候,反射也随之减少。使用基于物理的透光性.transmission 属性可以让一些很薄的透明表面,例如玻璃,变得更真实一些。
  • 高级光线反射: 为非金属材质提供了更多更灵活的光线反射。

来源:MeshPhysicalMaterial – three.js docs (threejs.org)

参考资料:

Three.js 贴图效果一览 - 知乎 (zhihu.com)

Three.js 之 7 Materials 材质 - 掘金 (juejin.cn)

# 三、3d 文字

​ 引入文体的时候,文件必须是 json 格式的,Facetype.js (gero3.github.io) 可以使用这个将文体转化为 json 格式。不过 three/examples/fonts 这里就有许多文体供我们使用了,不过好像不支持中文,使用中文的时候出现了?问号。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { FontLoader }  from 'font'
import {TextGeometry} from 'textGeometry'
const fontLoad = new FontLoader()
fontLoad.load(url,(font)=>{
const text = new TextGeometry(text(文本),{
font, 文体
size: 大小
height: 厚度
curbeSegments:文本曲线细分段数
bevelEnabled: 斜角效果
bevelThickness: 斜角厚度
bevelOffset: 斜角大偏移量
bevelSize: 斜角大小
bevelSegments: 斜角细分段数
})
const material = new THREE.MeshBasicMaterial() //创建材质
const mesh = new THREE.Mesh(text,material)
scene.add(mesh)
renderer.render(scene,camera) //重新渲染
},()=>{},()=>{}) //三个回调函数与TextureLoad一样。