对象、属性、构造参数

对象、属性与构造参数

你可以使用 three.js 的整个对象目录和所有属性。如有疑问,请随时查阅文档。

<mesh
  visible
  userData={{ hello: "world" }}
  position={new THREE.Vector3(1, 2, 3)}
  rotation={new THREE.Euler(Math.PI / 2, 0, 0)}
  geometry={new THREE.SphereGeometry(1, 16, 16)}
  material={
    new THREE.MeshBasicMaterial({
      color: new THREE.Color("hotpink"),
      transparent: true,
    })
  }
/>

问题是,所有这些属性将总是被重新创建。相反,你应该声明性地定义属性。

<mesh
  visible
  userData={{ hello: "world" }}
  position={[1, 2, 3]}
  rotation={[Math.PI / 2, 0, 0]}
>
  <sphereGeometry args={[1, 16, 16]} />
  <meshStandardMaterial color="hotpink" transparent />
</mesh>

构造函数参数

在 three.js 中,对象是被实例化的类。这些类可以接受一次性的构造参数(new THREE.SphereGeometry(1, 32)),以及属性(someObject.visible = true)。在 React Three Fiber 中,构造器参数总是通过 args 以数组形式传递。如果 args 后来改变了,对象自然必须从头开始重构!

<sphereGeometry args={[1, 32]} />

所有属性的底层对象都有一个.set()方法,可以直接接收 set 所需要的参数。例如,THREE.Color.set 可以接受一个颜色字符串,所以你可以简单地写出 color={new THREE.Color(‘hotpink’)}而不是 color=“hotpink”。有些设置方法需要多个参数,例如 THREE.Vector3,在这种情况下,给它一个数组 position={[100, 0, 0]}。

<mesh position={[1, 2, 3]} />
  <meshStandardMaterial color="hotpink" />

有 setScalar 方法的属性(例如 Vector3)可以这样设置。

// Translates to <mesh scale={[1, 1, 1]} />
<mesh scale={1} />

如果你想深入到嵌套属性(例如:Mesh.rotation.x),只需使用破折号。

<mesh rotation-x={1} material-uniforms-resolution-value={[512, 512]} />

处理非场景对象

你也可以将非 Object3D 基元(几何体、材料等)放入渲染树。它们的属性和构造参数与平时一样。你可能想知道为什么要把通常不属于 Scene 的东西放到 Scene 中,至少在一个 vanilla three.js 应用程序中是这样。与你声明任何对象的原因相同:它变得可管理、可反应和自动处置。这些对象在技术上不是场景的一部分,但它们 attach 于一个父对象,而这个父对象是 Scene 的一部分。

使用 attach 将对象绑定到它们的父级。如果你取消了附加的对象,它将自动从它的父对象上取下。以下是将一个材质附加到网格的 material 属性,将一个几何体附加到几何体属性。

<mesh>
  <meshBasicMaterial attach="material">
  <boxGeometry attach="geometry">

// Attach bar to foo.a
<foo>
  <bar attach="a" />

// Attach bar to foo.a.b and foo.a.b.c (nested object attach)
<foo>
  <bar attach="a-b" />
  <bar attach="a-b-c" />

// Attach bar to foo.a[0] and foo.a[1] (array attach is just object attach)
<foo>
  <bar attach="a-0" />
  <bar attach="a-1" />

// Attach bar to foo via explicit add/remove functions
<foo>
  <bar attach={(parent, self) => {
    parent.add(self)
    return () => parent.remove(self)
  }} />

// The same as a one liner
<foo>
  <bar attach={(parent, self) => (parent.add(self), () => parent.remove(self))} />

实际场景中可以如下使用:

- <directionalLight
-   castShadow
-   position={[2.5, 8, 5]}
-   shadow-mapSize={[1024, 1024]}
-   shadow-camera-far={50}
-   shadow-camera-left={-10}
-   shadow-camera-right={10}
-   shadow-camera-top={10}
-   shadow-camera-bottom={-10}
- />

+ <directionalLight castShadow position={[2.5, 8, 5]} shadow-mapSize={[1024, 1024]}>
+   <orthographicCamera attach="shadow-camera" args={[-10, 10, 10, -10]} />
+ </directionalLight>
上一页