这是关于 Fiber 内部工作机制的高级指南,如果你是刚开始了解,最好先去看看introduction 的内容,从那里开始了解
How does it work? 是如何工作的?
React Three Fiber 是threejs 的 React renderer(渲染器)。
Creating THREE objects 创建三维物体
在 threejs 中我们创建新的三维对象用的是传统的 JS API:
这意味着每个Fiber组件实际上将创建一个新的THREE对象,该对象将添加到场景中。虽然不一定需要理解这是如何工作的才能使用Fiber,但它将更好地帮助您处理在项目中可能需要的任何内容,阅读其他人的Fiber代码,甚至帮助你对其他的代码库做出贡献。
让我们看一个简单的 React 例子:
如果是 threejs 代码,那么相当于是这样:
我们的Canvas元素将创建一个新的场景,Fiber将为每个组件实例化新的对象,并在场景数据中正确地将它们组合在一起!
此外,Fiber将:
— 在[0,0,0]处设置一个新的透视相机,并将其设置为默认值
— 设置具有onPointer属性的所有网格上的射线投射指针事件
— 设置色调映射
— 自动处理窗口调整大小
让我们来更深入了解一下!
对象的创建由Fiber渲染器悄悄地处理,BoxGeometry构造函数的名称等效于驼峰式组件<boxGeometry />,而构造函数参数 - 在我们的示例中为[1, 2, 3] - 通过 args 参数传递:
注意只有组件第一次被添加到 React Tree 上时才会自动创建 object
The attach props attach 属性
Fiber始终尝试正确地推断组件与其父组件之间的关系,例如:
我们知道 group 可以能有 children,所以 Fiber 会调用 group 实例上的add 方法:
对于mesh和其他three.js对象,规则可能不同。查看three.js文档,我们可以看到如何使用材料和几何体构建THREE.Mesh对象。
使用attach 属性,我们可以精确地告诉渲染器将每个组件附加到哪个属性:
这其实相当于精确的告诉 Fiber 该这样进行渲染:
正如您所看到的,attach属性告诉Fiber将父级的材质属性设置为对我们的<meshNormalMaterial />对象的引用。
请注意,虽然我们在此示例中使用了几何体和材料,但Fiber还从构造函数名称推断出attach属性,因此任何具有material(材质)或 geometry(几何体)的内容都将自动附加到其父级的正确属性上。
Props 属性
使用 Fiber,你可以传递任何Threejs 属性作为 React 属性,只要那个属性在 threejs 相应的类型上有,设置之后该属性和值会被设置到构造出来的相应类型的实例对象上:
react 的代码相当于这些 threejs 代码:
Fiber将检查属性值的类型,然后执行以下操作之一:
— 直接分配新值
— 如果值是具有set方法的对象,则调用该方法
— 如有必要构造新对象。
— 在格式之间进行转换
react 的代码相当于这些 threejs 代码:
Pointer Events 指针事件
指针事件由Fiber自动处理。启动时,它会为鼠标拾取创建一个射线投射器raycaster。
每个带有onPointer属性的对象都将添加到每帧由射线投射器检查的对象数组中:
每次鼠标移动到<Canvas/>元素上或调整窗口大小时,都会更新射线的起点和方向。Fiber还处理相机切换,这意味着射线投射器将始终使用当前活动的相机。
使用raycast属性时,将使用自定义射线选择对象:
Render Loop 渲染循环
默认情况下,Fiber将设置一个渲染循环,从默认相机渲染默认场景到WebGLRenderer。
循环通过setAnimationLoop进行设置,每当有新的可渲染帧时,它将执行其回调。这是每次渲染时会发生的事情:
— 执行所有global before effects (全局前效果)
— 时钟增量被保存-意味着所有useFrame调用将共享相同的增量
— 按顺序执行useFrame回调
— 调用renderer.render(scene, camera),有效地将场景渲染到屏幕上
— 执行所有global after effects (全局后效果)