探索三维世界【3】:Three.js 的 Geometry 几何体 与 Material 材质
探索三维世界【3】:Three.js 的 Material 材质
- 1、Geometry几何体
- 2、Material 材质
- 3、创建平面与材质
- 4、多平面渲染
1、Geometry几何体
Three.js中的几何体Geometry是构成3D模型的基本单元之一,它定义了一个物体的形状和大小。Geometry包含了物体的顶点、面、法线、UV映射、颜色等信息,它可以定义各种各样的形状,例如三角形、矩形、圆形、立方体等等。
在使用Three.js创建物体时,需要将Geometry传入到Mesh对象中,Mesh对象则用于定义物体的材质和纹理等属性。Geometry可以通过手动指定顶点和面来创建,也可以通过使用Three.js中自带的多种几何体构造函数来创建,例如BoxGeometry、SphereGeometry、CylinderGeometry等等。
需要注意的是,使用Geometry创建物体时,需要手动计算并设置物体的法线以及UV映射等属性,这一过程有些繁琐。为了简化这一过程,Three.js还提供了BufferGeometry类,它可以自动计算这些属性,提高渲染效率和性能。
2、Material 材质
Three.js 中的 Material 材质是用于决定物体表面颜色、反射度、透明度等外观特性的对象。Material 材质有着很多不同的类型。
- BasicMaterial:对物体简单着色,只显示颜色和线框,不进行光照计算。
- LambertMaterial:光照模型中的漫反射计算,可以反射入射光,但是没有高光。
- PhongMaterial:光照模型中的高光反射计算,不仅计算漫反射,还计算镜面反射,有金属光泽感或亮面感。
- TextureMaterial:使用纹理贴图作为物体的贴图,可以设置细节、阴影、透明度等效果。
Material 材质还有许多不同的属性设置,如透明度、反射率、金属光泽度等。在 Three.js 中,可以根据需求选择合适的 Material 材质类型来创建物体的外观效果。
3、创建平面与材质
在这里创建一个简单的平面,其中BufferGeometry是面片、线或点几何体的有效表述。包括顶点位置,面片索引、法相量、颜色值、UV 坐标和自定义缓存属性值。同时创建基础网格材质MeshBasicMaterial是一个以简单着色(平面或线框)方式来绘制几何体的材质。这种材质不受光照的影响。最后将几何体与材质通过Mesh对象创建,Mesh是构成3D物体的基本单元之一,它是由Geometry和Material组合而成的。Geometry表示物体的形状和大小,而Material则表示物体的外观和纹理。Mesh还具有位置、旋转、缩放等属性,这些属性可以用来控制物体的位置和变形。在使用Mesh对象时,通常需要将其添加到场景中,才能够被渲染出来。可以使用Scene对象的add方法将Mesh对象添加到场景中。
注:Mesh对象只能够代表单个物体,不能用来代表多个物体。如果需要表示多个物体,可以考虑使用Three.js中的Group对象。此外,对于大量几何体,使用BufferGeometry而非Geometry可以提高渲染性能。
// 几何体与材质
const geometry = new THREE.BufferGeometry(1, 1, 1);
const vertices = new Float32Array([
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, -1.0, 1.0
])
geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
const cube = new THREE.Mesh(geometry, material);
// 设置位置
cube.position.set(0, 0, 0)
scene.add(cube);
查看效果:
4、多平面渲染
在这里我们使用循环随机绘制50个三角形平面,其中整体逻辑和上面是一样的, 并且给每一个三角形平面都设置了一个透明度和颜色随机,这样就可以看到如下效果
for (let i = 0; i < 50; i++) {
// 几何体与材质
const geometry = new THREE.BufferGeometry(1, 1, 1);
const vertices = new Float32Array(9)
for (let j = 0; j < 9; j++) {
vertices[j] = Math.random() * 5
}
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
let color = new THREE.Color(Math.random(), Math.random(), Math.random())
const material = new THREE.MeshBasicMaterial({
color,
// transparent设置为true 才可设置透明度
transparent: true,
opacity: 0.5
});
const cube = new THREE.Mesh(geometry, material);
// 设置位置
cube.position.set(0, 0, 0)
scene.add(cube);
}
查看效果