什么,竟有人把ThreeJS和React绑定在一起,混着用?
1、VUE劫持问题
暂先把今天的问题先放一边,先简单回顾下vue劫持的情况。vue会把data里面的数据自动转换为属性,方便界面与数据交互。这本身是没有任何问题,虽然DOM操作(如位置调整)会消耗一定的计算,但一般情况下还是可以接受的。
但到了三维渲染,情况就不同了。三维引擎并非采用缓存静态绘制(双缓冲技术)的技术,而是实时绘制。它会每秒30帧去请求三维场景的实体(Entity),如果三维场景被VUE托管成属性了,那就等于每帧都需要去请求一次getter函数。性能消耗是非常大的。
2、今天的示例效果
今天的示例的主角是一个狐狸,可以在《PS1-inspired Jitter Shader (tympanus.net)》中访问。右键可以让这个狐狸跑起来,也可以让狐狸变成马赛克状。
跑步可能没有什么特殊技术。但别着急,深入研究代码,会慢慢发现作者有几个技术创新。
聪明的你一定想到标题,那么技术创新一定包含React+ThreeJS的融合使用。是的,但是我们也应该清晰的认识到,框架这东西有好有坏。在坏的情况下,你无法从框架应用中学到任何东西,到头来被新框架抛弃。因此,我们今天先谈做法,再简单说说框架。
3、如何构建棋盘地面?
制作棋盘地面第一感觉是采用贴图,但该技术需要额外的贴图,有点不划算。另外还需要考虑地面移动的问题。本示例采用的是Shader技术,代码也简单,即根据Position设置A、B两种颜色,并且可以响应时间动画及手机端的适配问题。
4、马赛克模型
一般的马赛克做法是后处理,是采用某点的颜色并替换为周边几个像素的颜色。但上图的效果不一样,有明显的三角尖锐化效果。
有了“三角尖锐化效果”做引导,那么技术也是自然就容易发现。即在顶点着色器阶段,对顶点的位置进行偏移。代码如下:
gl_Position.xy /= gl_Position.w;
gl_Position.xy = floor(gl_Position.xy * uJitterLevel) / uJitterLevel* gl_Position.w;
上述代码可能难以理解的是为啥先要除以 gl_Position.w。这是因为gl_Position.w表示深度信息,即w是顶点距离相机的距离。w也可以理解为透视除法的因子。通过透视除法,得到归一化设备坐标(Normalized Device Coordinates, NDC)。此时,gl_Position.xy
的范围通常在 [-1, 1] 之间。
5、骨骼动画
我们日常接触的glTF模型一般是静态的,动态的glTF是什么样的呢?其中Animation存储了运动状态,比如跑步、停止,Armature存储了骨骼。
6、React-three-fiber
最后回到本示例中引用的框架React-three-fiber,
React-three-fiber 是一个基于React 的 3D 渲染库,它将 three.js 的强大渲染能力与 React 的声明式编程模型相结合。使用 react-three-fiber,您可以使用 React 的组件化开发方式来创建复杂的 3D 场景,同时利用 React 的状态管理和生命周期钩子来控制场景的交互和动画。
简单的说该框架简化了一些复杂的ThreeJS的对象操作,比如下面的代码,可以非常清晰的明白在渲染Canvas中添加了一个Mesh,该Mesh是一个Box,并且采用标准的材质。
总的来说,该框架可以减轻一部分的代码编程,给我们一些新的启发。不过也得辩证的看待该框架。该框架并非基础性、革命性的框架,采用HTML的组织模式跟JSON格式的场景组织都能达到相同的效果。因此如果你将使用该框架,先看看哪些是你最需要的。