第四章:几何体(Geometries)和材质(Materials)

7/19/2023 ReactThree.js

在本章节中,我们将深入学习如何在React+Three.js应用程序中创建和编辑Three.js几何体,并使用React组件来管理几何体和材质。我们还将学习如何实时更新和交互几何体和材质,使我们的场景更加生动和有趣。

# 1. 创建和编辑Three.js几何体

在Three.js中,几何体(Geometries)是3D对象的形状。Three.js提供了许多内置的几何体,如立方体、球体、圆柱体等,我们也可以通过顶点坐标来创建自定义的几何体。

让我们来创建一个简单的自定义几何体,并在场景中显示它:

import React, { useRef, useEffect } from 'react';
import * as THREE from 'three';

const ThreeScene = () => {
  // ...

  useEffect(() => {
    // ...

    // 创建一个自定义的几何体
    const customGeometry = new THREE.Geometry();
    customGeometry.vertices.push(
      new THREE.Vector3(0, 0, 0),
      new THREE.Vector3(1, 1, 0),
      new THREE.Vector3(-1, 1, 0),
      new THREE.Vector3(0, 1, 1)
    );
    customGeometry.faces.push(new THREE.Face3(0, 1, 2));
    customGeometry.faces.push(new THREE.Face3(0, 1, 3));
    customGeometry.computeFaceNormals();

    const customMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true });
    const customMesh = new THREE.Mesh(customGeometry, customMaterial);
    scene.current.add(customMesh);

    // ...

  }, []);

  // ...

  return <div ref={sceneRef} />;
};

export default ThreeScene;
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

在上述代码中,我们创建了一个自定义的几何体,它由四个顶点和两个三角面组成。我们使用THREE.Geometry类来定义几何体的结构,然后创建了一个简单的绿色线框的材质,并将几何体和材质添加到场景中。

# 2. 使用React组件管理几何体和材质

在React中,我们可以使用组件来管理我们的Three.js几何体和材质。通过创建可复用的组件,我们可以更好地组织和管理我们的3D场景中的元素。

让我们来创建一个名为CustomGeometry的React组件,用于显示我们之前创建的自定义几何体:

import React, { useRef, useEffect } from 'react';
import * as THREE from 'three';

const CustomGeometry = () => {
  const meshRef = useRef(null);

  useEffect(() => {
    // 创建自定义几何体和材质
    const customGeometry = new THREE.Geometry();
    customGeometry.vertices.push(
      new THREE.Vector3(0, 0, 0),
      new THREE.Vector3(1, 1, 0),
      new THREE.Vector3(-1, 1, 0),
      new THREE.Vector3(0, 1, 1)
    );
    customGeometry.faces.push(new THREE.Face3(0, 1, 2));
    customGeometry.faces.push(new THREE.Face3(0, 1, 3));
    customGeometry.computeFaceNormals();

    const customMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true });
    const customMesh = new THREE.Mesh(customGeometry, customMaterial);
    meshRef.current = customMesh;

    // 在组件卸载时,清理几何体
    return () => {
      customGeometry.dispose();
      customMaterial.dispose();
    };
  }, []);

  return <primitive object={meshRef.current} />;
};

export default CustomGeometry;
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

在上述代码中,我们创建了一个名为CustomGeometry的React组件。在该组件的useEffect钩子中,我们创建了我们之前所述的自定义几何体,并在组件卸载时清理几何体。然后,我们使用<primitive>元素来渲染我们的自定义几何体,通过object属性来传递我们的几何体对象。

现在,我们可以在ThreeScene组件中使用CustomGeometry组件来显示我们的自定义几何体:

import React, { useRef, useEffect } from 'react';
import * as THREE from 'three';
import Custom

Geometry from './CustomGeometry';

const ThreeScene = () => {
  // ...

  useEffect(() => {
    // ...

    // 在场景中添加CustomGeometry组件
    const customMesh = new THREE.Object3D();
    customMesh.add(CustomGeometry());

    scene.current.add(customMesh);

    // ...

  }, []);

  // ...

  return <div ref={sceneRef} />;
};

export default ThreeScene;
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

在上述代码中,我们在ThreeScene组件中使用CustomGeometry组件来显示我们的自定义几何体。我们首先创建一个Object3D对象customMesh,并将CustomGeometry组件添加为其子对象。然后,我们将customMesh添加到场景中。

通过这种方式,我们可以使用React组件来管理和组织我们的3D场景中的元素,使代码更加清晰和易于维护。

# 3. 实时更新和交互几何体和材质

在React+Three.js应用程序中,我们可以实现实时更新和交互几何体和材质。这为用户提供了更好的体验和更多的交互性。

例如,让我们添加一个按钮来切换自定义几何体的显示模式(线框或实体):

import React, { useRef, useEffect, useState } from 'react';
import * as THREE from 'three';
import CustomGeometry from './CustomGeometry';

const ThreeScene = () => {
  // ...

  // 使用useState来跟踪自定义几何体的显示模式
  const [wireframe, setWireframe] = useState(true);

  useEffect(() => {
    // ...

    // 创建一个Object3D来容纳CustomGeometry组件
    const customMesh = new THREE.Object3D();
    customMesh.add(CustomGeometry());
    scene.current.add(customMesh);

    // ...

  }, []);

  // 切换自定义几何体的显示模式
  const toggleWireframe = () => {
    setWireframe((prevWireframe) => !prevWireframe);
  };

  return (
    <div>
      <div ref={sceneRef} />
      <button onClick={toggleWireframe}>切换显示模式</button>
    </div>
  );
};

export default ThreeScene;
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
36

在上述代码中,我们使用useState钩子来跟踪自定义几何体的显示模式(线框或实体)。我们添加了一个按钮,并通过点击按钮来切换自定义几何体的显示模式。

然后,在CustomGeometry组件中,我们根据wireframe状态来设置自定义几何体的材质:

// CustomGeometry.js

import React, { useRef, useEffect } from 'react';
import * as THREE from 'three';

const CustomGeometry = ({ wireframe }) => {
  const meshRef = useRef(null);

  useEffect(() => {
    const customGeometry = new THREE.Geometry();
    // ...

    const customMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: wireframe });
    const customMesh = new THREE.Mesh(customGeometry, customMaterial);
    meshRef.current = customMesh;

    return () => {
      customGeometry.dispose();
      customMaterial.dispose();
    };
  }, [wireframe]);

  return <primitive object={meshRef.current} />;
};

export default CustomGeometry;
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

CustomGeometry组件中,我们通过wireframe属性来接收ThreeScene组件中的状态。然后,我们在几何体的材质中根据wireframe状态来设置wireframe属性,以切换显示模式。

通过这种方式,我们实现了实时更新和交互几何体和材质,使用户可以通过按钮来切换自定义几何体的显示模式,增加了更多的交互性和体验。

在下一章节中,我们将学习如何在React+Three.js应用程序中添加光源来增强场景的效果,以及如何应用纹理和材质来让场景更加逼真。敬请期待!

编辑时间: 7/19/2023, 10:30:56 AM