[Three.js] 几何体、材质、网格

profile image

了解构成Three.js中3D对象的三个核心元素:几何体、材质和网格。

本帖由 Jetbrains's Coding Agent Junie junie logo翻译。如有任何翻译错误,请告知我们!

让我们了解构成Three.js中3D对象的三个核心元素:几何体、材质和网格。

什么是几何体?

几何体是定义3D对象形状的顶点(vertices)、面(faces)和线(line)的集合。简单来说,可以将其视为3D物体的"骨架"。 让我们看看下面的示例代码。

typescript
// 创建自定义三角形
const geometry = new THREE.BufferGeometry();

// 三角形的顶点坐标
const vertices = new Float32Array([
    -1.0, -1.0, 0.0,  // v0
     1.0, -1.0, 0.0,  // v1
     0.0,  1.0, 0.0   // v2
]);

// 作为缓冲属性分配给几何体
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));

通过这种方式,可以传递矩阵形式的数据在屏幕上进行渲染。更多相关选项可以在官方文档链接中找到。

基本几何体类型

Three.js提供了各种用于创建基本形状的几何体类。

typescript
// 立方体
const boxGeometry = new THREE.BoxGeometry(width, height, depth);

// 球体
const sphereGeometry = new THREE.SphereGeometry(radius, widthSegments, heightSegments);

// 平面
const planeGeometry = new THREE.PlaneGeometry(width, height);

// 圆柱体
const cylinderGeometry = new THREE.CylinderGeometry(radiusTop, radiusBottom, height);

// 圆锥体
const coneGeometry = new THREE.ConeGeometry(radius, height);

// 圆环体(甜甜圈形状)
const torusGeometry = new THREE.TorusGeometry(radius, tube, radialSegments);

什么是材质?

材质定义了3D对象的外观。它包括决定对象如何呈现的所有视觉属性,如颜色、透明度、纹理等。它使用以下主要属性。

typescript
const material = new THREE.MeshStandardMaterial({
    // 基本属性
    transparent: true,     // 是否使用透明度
    opacity: 0.5,         // 不透明度(0.0 ~ 1.0)
    side: THREE.DoubleSide, // 双面渲染
    visible: true,        // 可见性
    wireframe: false,     // 线框模式

    // 颜色相关
    color: 0xff0000,      // 基本颜色
    emissive: 0x000000,   // 自发光颜色

    // 等等...
});

主要材质类型和特点

1. MeshBasicMaterial

最简单的材质,不受光照影响。性能好,适合简单用途。由于没有光照计算,可以最快速地渲染。

2. MeshStandardMaterial

使用基于物理的渲染(PBR,Physically based rendering)的材质。PBR基于实际物理规律模拟光的相互作用,产生非常逼真的结果。因此,与其他材质相比,渲染计算成本更高。

3. MeshPhongMaterial

MeshPhongMaterial适合表现有光泽的表面。它使用Phong着色模型计算高光和反射光,常用于表现塑料或陶瓷等材质。

typescript
new THREE.MeshBasicMaterial({
  color: color,
  side: THREE.DoubleSide,
});
new THREE.MeshStandardMaterial({
  color: color,
  roughness: 0.5,
  metalness: 0.5,
  side: THREE.DoubleSide,
}),
new THREE.MeshPhongMaterial({
  color: color,
  shininess: 60,
  specular: 0x444444,
  side: THREE.DoubleSide,
}),

MeshBasicMaterial

MeshStandardMaterial

MeshPhongMaterial

贴图的基本概念和类型

材质可以使用各种贴图使对象的外观更加逼真和丰富。贴图提供了一种将纹理映射到3D对象表面的方法,每种贴图用于控制不同的视觉特性。

1. map

应用基本颜色纹理的贴图。

typescript
const textureLoader = new THREE.TextureLoader();
const colorTexture = textureLoader.load('hangyodon.avif');

const material = new THREE.MeshStandardMaterial({
    map: colorTexture
});

2. normalMap

表现表面细节的贴图。

typescript
const normalTexture = textureLoader.load('hangyodon.avif');

const material = new THREE.MeshStandardMaterial({
    normalMap: normalTexture,
    normalScale: new THREE.Vector2(1, 1)  // 调整法线贴图强度
});

3. roughnessMap

控制表面粗糙度的贴图。与MeshStandardMaterial一起使用。

typescript
const roughnessTexture = textureLoader.load('hangyodon.avif');

const material = new THREE.MeshStandardMaterial({
    roughnessMap: roughnessTexture,
    roughness: 1.0  // 默认粗糙度值
});

Meshmap

MeshnormalMap

MeshroughnessMap

网格

网格是将充当骨架的几何体和定义外观的材质结合起来的对象。在Three.js中,网格是继承自Object3D的类,用于创建可以在3D空间中渲染的对象。

typescript
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

网格的属性和方法

位置(Position)

typescript
// 设置位置
mesh.position.set(x, y, z);
// 或者
mesh.position.x = 1;
mesh.position.y = 2;
mesh.position.z = 3;

旋转(Rotation)

typescript
// 设置位置
mesh.position.set(x, y, z);
// 或者
mesh.position.x = 1;
mesh.position.y = 2;
mesh.position.z = 3;

缩放(Scale)

typescript
// 设置缩放
mesh.scale.set(x, y, z);
// 或者
mesh.scale.x = 2;  // X轴方向放大2倍
mesh.scale.y = 0.5; // Y轴方向缩小为0.5倍
mesh.scale.z = 1;   // Z轴无变化

总结

我们已经了解了Three.js的核心组件。我们可以用几何体定义3D对象的形状,用材质表达对象的视觉特性,并通过结合这两者的网格创建实际在屏幕上渲染的3D对象。

在本文中,我们通过基本示例探讨了核心概念,但Three.js提供了更多样化和强大的功能,值得以后更详细地探索。

此外,由于3D图形的特性,对象越复杂,需要的计算资源就越多。因此,在实际项目中,应该注意以下几点!(否则在移动设备上经常会崩溃...

  • 维持适当的多边形数量
  • 释放不必要对象的内存

参考

❤️ 0
🔥 0
😎 0
⭐️ 0
🆒 0