对象属性与传参
Declaring object(声明对象)
可以使用Threejs中所有的对象目录和属性
方法1:你可以这样来创建一个对象,但是不推荐,这个方式会导致重复创建的问题:
<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 })}
/>
方法2:声明式的方式来创建元素:
<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>
Constructor 构造参数
Threejs中的对象一般都是需要进行实例化的类型。这些类型通常都是在实例化时传入参数(new THREE.SphereGeometry(1, 32)),或者通过实例的属性来进行设置(someObject.visible = true)。
在React Three Fiber中,这些实例化时传入的参数一般都通过 args属性来穿日。如果args属性的后来数据发生了变化,那么相应的对象会被强制重新构建。
<sphereGeometry args={[1, 32]} />
简化写法
Set
所有具有 .set() 方法的类型实例的属性在通过JSX语法进行创建时,都可以直接接收与 set 方法相同的参数。例如,THREE.Color.set 可以接收颜色字符串,因此可以只写 color="hotpink",而不是 color={new THREE.Color('hotpink')}。一些 set 方法接受多个参数,例如 THREE.Vector3,在这种情况下,您可以给它一个数组,如 position={[100, 0, 0]}。
<mesh position={[1, 2, 3]} />
<meshStandardMaterial color="hotpink" />
如果将现有对象链接到属性,例如将 THREE.Vector3() 链接到position属性,则请注意,这通常会复制对象,因为它会在目标上调用 .copy()。这仅适用于同时拥有 .set() 和 .copy()(向量、欧拉角、矩阵等)的对象。另一方面,如果将现有材质或几何体链接起来,则会进行覆盖,因为这些对象没有 .set() 方法。
SetScalar
某个属性如果有setScalar方法(比如说Vector3),那么可以这样写:
// Translates to <mesh scale={[1, 1, 1]} />
<mesh scale={1} />
Piercing into nested properties(穿透设置)
如果你想要设置被嵌套的属性(比如:mesh.rotation.x),可以使用短横线的写法:
<mesh rotation-x={1} material-uniforms-resolution-value={[512, 512]} />
Dealing with non-scene objects(处理非场景对象)
你也可以将非Object3D元素的一些原始数据(几何体、材料等)放入渲染树中。它们使用方式与一般的属性和构造函数参数是一样的。
你可能会想知道为什么在一个普通的Three.js应用程序中,要将不属于场景的东西放入“场景”中。这和声明任何对象的原因相同:它变得易于管理,响应和自动释放。这些对象在技术上不属于场景,但它们“附加Attach”到一个属于场景的父对象上。
Attach
使用attach属性可以把数据绑定到他们的父级上。如果你卸载了某个绑定的数据,那么它会自动从父元素上解除掉绑定。
下面的这代码就是把一个材质数据斌定到了个mesh元素的material属性上,把一个geometry数据绑定到了geometry属性上。
<mesh>
<meshBasicMaterial attach="material">
<boxGeometry attach="geometry">
Disposal 处理(销毁)
在 three.js 中释放资源是一个手动的繁琐过程,但 React 知道对象的生命周期,因此 React Three Fiber 将尝试通过调用所有未安装对象上的 object.dispose()(如果存在)来为释放资源。
如果你是自己手动管理全局或缓存中的资产,则可能不是你想要的。您可以通过在网格、材质等上放置 dispose={null} 来关闭它,甚至可以在像组这样的父容器上放置它,这对整个节点树都是有效的。
const globalGeometry = new THREE.BoxGeometry()
const globalMaterial = new THREE.MeshBasicMaterial()
function Mesh() {
return (
<group dispose={null}>
<mesh geometry={globalGeometry} material={globalMaterial} />