欢迎光临散文网 会员登陆 & 注册

自制React-three-fiber

2022-10-27 12:01 作者:TongMarsh  | 我要投稿

🐜Threejs101

代码1 设置了舞台,创建了三个基本组件:renderer, scene, camera

代码2 往场景中增加物体,将根节点加到dom里

代码3 定义renderLoop

通过上面的代码,可以创建出一个几何体

👼拥抱React

Canvas组件

为了在React中使用Threejs,可以创建一个Canvas组件,代码如下:

组件中只封装了canvas,在hook中定义了设置舞台的代码,定义了renderLoop,并且开启了render loop,现在要在页面中显示出物体,只差一步:创建物体,往场景中添加。

如何往场景(scene)里添加物体

选项1:  Javascript方式

直接就在hook里创建几何体,创建材质,再创建mesh,然后直接加到scene里

这样子的话,其实React只是一层皮,实际的Threejs完全就是当作普通JS代码在写

选项2: React jsx

这里需要知道的一个点是scene作为整个场景的根节点,其他所有的mesh都是往这里加,而每个mesh也可以有自己的child,整个场景是一个树状。我们要做的就是往树的根节点加节点,使用JS的方式就是我们显示创建,自己给加进去。而React创建dom树是通过声明式构建出的,所以也可以通过jsx声明式的方式创建mesh,让react帮我们构建场景树。

我们期望可以用下面方式创建场景

在Canvas组件内部通过jsx定义mesh,构建mesh的geometry,material通过props指定,然后React会自动给我创建mesh加到scene里。

自定义Renderer

React是如何创建dom的

React是由ReactDOM负责根据虚拟dom创建dom,并且加到根节点的,所以我们也需要一个类似的render函数

这个render函数类似ReactDOM的render函数,接收虚拟dom和场景根节点,然后帮我们创建mesh,加到scene里。

仿照ReactDOM写个render函数

创建一个renderer,render函数中通过renderer调用updateContainer去更新,我们需要实现传入Renconciler的参数。

填充Reconciler参数

拷贝十几个函数,我们关心的只有几个:createInstance,appendChild, appendChildToContainer, appendInitialChild,finalizeInitialChildren,因为只需实现这几个就可以完成渲染,而我只想明白为什么可以通过React渲染3D物体,不关心更新卸载等问题,所以其他函数不实现了。

  • createInstance函数:根据虚拟dom创建实例的方法,通过它可以创建自定义的标签节点,这里就是从Threejs里找到标签对应的类生成并返回。

  • finalizeInitialChildren:可以在这里做属性赋值的工作,也可以在createInstance直接就完成。

  • appendChild:将子节点加到父节点中,构建树状的方法

  • appendInitialChild:和上面那个一样,将子节点加到父节点(暂不清楚为什么要分两个方法)

  • appendChildToContainer:加到根节点中的方法

效果:

https://codesandbox.io/s/elastic-wood-ux0mkj?file=/src/App.js

免责声明

本篇文章完全是个人出于好奇,想了解为什么React-three-fiber可以用React语法写threejs应用,因此着重点在实现渲染的基本思路,对于更新卸载等都未关注。另外,使用到的react-reconciler也是老版本,对其api也未深入探索。


自制React-three-fiber的评论 (共 条)

分享到微博请遵守国家法律