r3f 自定义渲染器
r3f 自定义渲染器

r3f 自定义渲染器

react-three-fiber 自定义渲染器核心逻辑主要是在于 createRenderer 方法中如何将 Three.js 中的对象结构与 JSX 绑定到一起,并返回 ReconcilerapplyProps 用于对虚拟 DOM 的维护和更新。

绑定 Three 命名空间

interface Catalogue { [name: string]: { new (...args: any): Instance } } export const catalogue: Catalogue = {}; const extend = (objects: object): void => void Object.assign(catalogue, objects); React.useMemo(() => extend(THREE), []);
这里主要是将 THREE.Mesh 等缓存到 catalogue 中。

createInstance

该方法接收三个参数,typeInstanceProps 以及 rootStore
代表要创建的 Three.js 对象的类型(例如 'mesh'、'camera'、'light'),以及一个 InstanceProps 对象,其中包含了将要设置在实例上的属性,包括 args、attach 以及其他自定义属性。如果类型是 'primitive',意味着函数必须处理一个通过 object 属性直接传入的原始对象,原始对象是指不是由 R3F 创建而是直接传入的对象,可能是因为它在 React 外部被创建或者是被其他状态管理;
函数将创建 Three.js 对象,根据类型设置属性。类型包括 'mesh'、'camera'、'light',如果是 'primitive',则需要处理传入的原始对象。其他类型需以大写字母开头匹配 Three.js 类名,如:
<mesh ..../> const mesh = new THREE.Mesh(...);
如果是 BufferGeometry 或者 Material,则会被自动挂载到其父节点上。
<mesh> <meshBasicMaterial attach="material" /> <boxGeometry attach="geometry" /> </mesh> const geometry = new THREE.BoxGeometry( 1, 1, 1 ); const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); const mesh = new THREE.Mesh( geometry, material );
 

appendChild

function appendChild(parentInstance: HostConfig['instance'], child: HostConfig['instance']) { let added = false if (child) { // The attach attribute implies that the object attaches itself on the parent if (child.__r3f?.attach) { attach(parentInstance, child, child.__r3f.attach) } else if (child.isObject3D && parentInstance.isObject3D) { // add in the usual parent-child way parentInstance.add(child) added = true } // This is for anything that used attach, and for non-Object3Ds that don't get attached to props; // that is, anything that's a child in React but not a child in the scenegraph. if (!added) parentInstance.__r3f?.objects.push(child) if (!child.__r3f) prepare(child, {}) child.__r3f.parent = parentInstance updateInstance(child) invalidateInstance(child) } }
通过 attach 来决定 child 是其父节点属性或者 children,并更新实例。

applyProps

创建好 instance 之后调用 applyProps 函数,该函数将传入的属性应用到新实例上。这个函数处理设置属性、添加事件监听器、管理引用等

switchInstance

在 Reconciler 中存在 commitUpdate ,当需要重建节点时,会调用 switchInstance ,依据最新的 props 来生成最新的 instance,并将 r3f 子结构重新构建为新的节点 children。并删除旧结点,同时重新绑定事件。
 
一旦实例被创建和初始化,它就可以被插入到场景图中,并且其生命周期可以由调和器的其他方法(appendChild、removeChild 等)根据 React 调和器定义的 diffing 和更新过程来管理。