资源下载地址:https://download.csdn.net/download/sheziqiong/85610855
一、实验目的和要求
-
掌握 FFD 变形算法的思想与实现原理。
-
能够实现交互控制进行 FFD 三维变形。
二、实验内容和原理
根据 FFD 的原理,将某个三维模型嵌入一个可调整 box 内,通过交互操作嵌入空间的控制点,对嵌入其中的物体进行变形操作。要求控制点数量可以变化。
数学原理分析:
自由变形技术 Free-Form Deformation 是编辑几何模型的重要手段,它于 80 年代由 Siedberg 等人提出,目前许多三维建模软件中都有这种变形算法。自由变形方法在变形过程中并不是直接操作几何模型,而是把几何模型嵌入到变形空间,然后通过操作变形空间来使得嵌入其中的几何模型发生变形。
首先创建一个平行六面体的变形空间框架(Box),并将目标几何体嵌入该框架,建立世界坐标与局部坐标(相对坐标)的联系。公式如下:
其中,S、T、U是变形框架的三个方向向量。我们得出的局部坐标都是归一化了的,即 0<s<1,0<t<1,0<u<1。在整个变形的过程中,几何模型的顶点的局部坐标是不变的,只有世界坐标相应变化。
下面引入框架控制点 Pijk:
移动框架的控制点,利用几何模型顶点局部坐标、控制点世界坐标和 Bernstein 多项式重新计算新的顶点世界坐标:
其中 P(i, j, k)为框架控制点的新坐标,l、m、n 分别为在 S、T、U 坐标轴上划分的格子数目。上式也可以简单地写作:
其中 Bi(u)是 Bernstein 基函数,定义为:
三、实验器材
HTML5 + CSS+ JavaScript、 Three.js 三维库
工程依托 Visual Studio Code 完成
四、实验步骤
基本数据结构定义
1.构建嵌入空间,建立世界坐标与局部坐标的联系
在 Three.js 里,构建嵌入空间非常简单,调用 box 对象的setFromPoints 方法就可以实现:setFromPoints( points: Vector3[] ),设置此包围盒的上边界和下边界,以包含数组 points 中的所有点。根据公式:
实现方法如下:
2.构造控制点、估计点
预期效果是在包围盒上画出线框与控制点。所以写了如下绘制线框的代码:
其中 mEdge 变量是在每个方向上建立的单位向量。setPositionTernary 函数通过三元坐标设置控制点。
3.变形后几何体坐标的得到
Berstein 基函数的实现:
首先根据公式:
得到在局部坐标(即相对坐标)系下估计的点的坐标。
然后可以转换坐标系到世界坐标:
eval_pt(估计点)穿插在几何形体顶点之间,定义如下:
在变形过程中的代码如下:
如果要绘制中间估计点(插值点),那么只需要调用我们上面的 evalLocal 函数就可以得到插值点的位置。
附:调用的 Threejs 库包括:
- OrbitControl 库:视角轨道控制器,建立鼠标与屏幕的交互,可以拖动、缩放等等。
- TransformControl 库:交互变形控制器,自带类似于 Maya 操作界面的移动 UI 等。
- SubdivisionModifier 库:对几何体进行指定等级的细分。
本次实验重点在与 FFD 算法的复现,关于界面的实现,不是本次实验的重点,因此不在报告中赘述。
五、实验结果分析
更改 Span Count
变形与插值点的显示
其他模型
更多效果请看录屏演示
六、反思与总结
通过对 Siedberg 的论文的复现,理解了 FFD 的各个公式的意义,参数的意义。通过网页编程的框架,对网页交互的实现也更加娴熟。
WebGL 框架下的图形学渲染编程有点像 OpenGL,比较繁琐,但是效果很好。
对于变形方法,我发现在控制点变多的情况下,变形的效果会有所打折,这应该是受于公式所限。对于算法的改进,还可以再搜索一些资料,了解 FFD 的改进方法。
在很多 3D 建模软件里对于 FFD 变形都有了封装,基本上采用的都是 444 的控制网格。从现在实验的效果来看,当分段数大的时候,变形会比较细微。
参考资料
Three.js 的交互拾取 https://zhuanlan.zhihu.com/p/143642146
Three.js 高级材质:MeshLambertMaterial https://blog.csdn.net/qq_30100043/article/details/78047104
THREE.js 几何体 Geometry https://blog.csdn.net/yangnianbing110/article/details/51306653
Three.js 几何变换操作库 TransformControl https://www.jianshu.com/p/7858db822b62
Three.js Vector3 类源码说明 https://github.com/omni360/three.js.sourcecode/blob/master/Three.j
资源下载地址:https://download.csdn.net/download/sheziqiong/85610855