目录
一,介绍
二,原理
三,PBD算法
手动实现PBD的拉伸
一,介绍
Vellum是一个解算模拟框架,使用更高级的PBD(XPBD,extended position based dynamics),是2nd Order Integration(传统的PBD使用的是1nd Order Integration),不像PBD子步和迭代次数影响刚性(迭代越多越硬);由于Vellum Solver需对约束重复计算,为提高效率并行计算,引入Graph Color技术;Grain是使用PBD来模拟沙子或颗粒物的;
可被用于创建许多不同的东西,包括cloth、hair、softbodies、balloons、及grains;基于位置方法的主要优势,是其可控、稳定、快速生成可信结果;GPU友好对于并行约束解算,特别是使用graph color(Breaking Frequency会re-color);

Constraint Iteration约束迭代,对于高刚性和高精度使用更高的约束迭代,提高子步效果更好但也更贵;Collision Iteration碰撞迭代,关联到detangle节点,在约束迭代间穿插执行;Smooth Iteration平滑迭代,默认约束迭代使用Gauss-Seidel方法快速收敛,对于不可能的配置(如无限刚性和0.5倍的restlength)等无法完全收敛的则使用Jacobi方法更慢的收敛来分散错误;

每个vellum类型均可相互交互,即可直接将各个类型的发射源合并(merge)起来,还可使用POP Force,POP Stream等;通常cloth使用三角面;
几种类型的柔体:
- Cloth + Pressure,vellum configure balloon
- Cloth + Structs,vellum configure struct softbody
- Distance along edges + Tetrahedral volume
- Tet Conform + Tetrahedral Stretch,vellum configure Tetrahedral softbody
对布线不均的模型,应remesh使对象均匀布线,以为后续解算,最后在用解算的对象驱动原模型;

注,按住J连接其中一个,三个输入/输出会自动一起连接;
二,原理
本质上是点(有碰撞半径的球)及约束组成,PBD是一个动态系统,试图一个点一个点地relax约束和碰撞,只有再足够高的迭代次数下才会产生合理的结果;

有三种类型的约束:Distance/Length/Stretch 保持点间的距离(可认为是线性弹簧),Rotational/Bend 保持面间的角度(可认为是旋转弹簧),Volume 保持几何体的体积(tetrahedron); 在实际应用中,可以是其中一种或多种的组合;

三,PBD算法
- 循环所有粒子,根据力及速度,计算新位置
; - 循环所有约束,修正新位置
; - 循环所有粒子,根据最终的位置和起始位置,更新速度


迭代iteration和子步sub-steps
【文献导读】XPBD: Position-Based Simulation of Compliant Constrained Dynamics_beidou111的博客-CSDN博客
【物理模拟】PBD算法详解-CSDN博客
手动实现PBD的拉伸
参考: Implementing A Position Based Cloth Solver From Scratch – Entagma

// Verlet Integration vector cur_P = @P; vector old_P = v@old_P; vector force = v@force; @P = 2*@P - old_P + force * pow(@TimeInc,2); @old_P = cur_P;
讯享网
讯享网//satisfy constraints int constraints[] = pointprims(1, @ptnum); vector displacement = set(0,0,0); float weight = 0; foreach(int con; constraints){ int con_pts[] = primpoints(1, con); vector posa = point(0, 'P', con_pts[0]); vector posb = point(0, 'P', con_pts[1]); vector delta = posa - posb; float delta_len = length(delta); float restlength = prim(1, 'restlength', con); float error = (restlength - delta_len) * 0.5; float dir = 1; if(con_pts[0] != @ptnum) dir = -1; displacement += normalize(delta) * error * dir; weight += 1.0; } @P += displacement/weight;






版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/75610.html