|
/// 更新 2020-02-12
虽然三年前用pygame做时运行效率很渣,但是2020年了,我们有Taichi了啊,感谢大神 @胡渊鸣 :-)
用Taichi重写的PBF2D @60FPS
https://www.zhihu.com/video/1215031537483579392
/// 更新 2018-08-05
工程问题就要用工(cao)程(kuai)师(meng)的思维解决。XYZ三轴连扫,理清杂线。
https://www.zhihu.com/video/1009615422542508032
/// 更新 2018-06-23
看到好多童鞋回复炒豆/炒菜机器人,大家的关注点都很奇特啊…
不过各位慷慨的赞真的是给了我很大的动力,上周我决定写一个自定义场景的功能。大概思路是场景用各种模型文件(.obj)描述,这些模型决定了粒子团的位置。这相当于给定一个mesh和步长,对该模型进行voxelization:
龙:我很方
于是,炒兔模拟器诞生了...
https://www.zhihu.com/video/994085257263562752
可能有人会纳闷,兔子上那些凸出来的线是什么?
嗯,这大概就是voxelization算法界的卖家秀和买家秀了。大家diss时还望手下留情!
毕竟,龙也很方,我也很方...
附上我找到的一个voxelization算法:Eisemann, Elmar, and Xavier Décoret. "Single-pass GPU solid voxelization for real-time applications." In Proceedings of graphics interface 2008, pp. 73-80. Canadian Information Processing Society, 2008.
传统的算法是在每个点上发射线,判定跟模型相交几次。在没有octree等空间搜索数据结构的前提下,这个复杂度是 。而这篇文章的思路是,对mesh上每个三角形面片,找到该面片前面最近的那个点并+1。所有面片都这样操作完后,再做一次prefix scan。那么所有为奇数的点就是在mesh的内部了。这样相当于所有面片只算一次就够了!复杂度应该是 。
/// 原回答
看了好多有意思的回答,发现果然有界面的代码比命令行的炫酷很多...我也来安利一下自己的一个项目(在大家的支持下又更了!/** 已弃更 T.T */)。一年前做了一个基于粒子模型的流体模拟器,算法来自
Position Based Fluid (PBF)这篇论文。最终效果如下(渣画质见谅...):
https://www.zhihu.com/video/989493267066609664
完成这个项目大概需要的技能是:
一点儿C++/CUDA:用来疯狂地算!一点儿OpenGL/GLSL:用来生动地画!一点儿Visual Studio:除了大,VS真是一款梦幻IDE一个支持空间搜索的数据结构:我用的是最简单的空间网格(spatial grid, spatial hashing...)。其基本思想就是,将一个3D空间划分成一个个尺寸固定的小格(cell, voxel...参考Minecraft),每个小格存储所有在其内部的粒子的信息。这个思想的核心数据结构用几个数组就能搞定了,因此非常容易在GPU上实现。推荐这篇:NVIDIA - Particle Simulation using CUDA*一点儿线性代数,即矩阵运算与线性变换的关系。这主要是为了实现摄像机,如果用现有3D框架的话并非必需。当然了,线性代数是计算机图形学(CG)的基础,真想学CG的话这块儿知识还是很有必要掌握的。
用其他语言行吗?当然,只是个人倾向于原生态的CUDA/OpenCL,用着舒服、省心...
//////////////////
最开始我是在一堂课上看到了这个视频(需翻墙),当时就被其仿真效果惊艳到了。
YouTube - Position Based Fluids - SIGGRAPH submission video
看完了乐呵了就把这事忘了...直到毕业后有次碰巧看到了PBF这篇论文,惊喜的发现这里面的数学运算比较简单,基本就是些向量运算,属于学过线性代数就可以徒手开撸的项目。于是码农独有的中二病爆发,我花了一周,重新实现了一遍paper。
...才怪
//////////////////
做这个的过程还是挺一波三折的。
决心实现一遍论文的时候我正在准备面试。一开始的打算就是拿python快速实现个2D demo,满足一下自己的好奇心就行。于是随便看了看后,拉了个pygame包就糙快猛地干了两周。
一运行,粒子炸了。一切尽在预料之中。
断断续续地debug了一阵后,算法终于算是稳定下来了,粒子不再会跑几帧后就“挥一挥衣袖, 不带走一片云彩”了。但我用python的姿势水平还是太渣。这个版本没有任何绘图方面的优化,三位数的粒子就能让程序处于幻灯片水准了。这性能差得让我直接失去了继续debug的动力——就算是bug free,几十个粒子大概是毛液体效果也看不出了。
元气大伤,怒删代码,饮恨封刀,专心刷题三个月。
顺利搞定面试后,手又痒了——自己最开始入门编程就是因为想做游戏,学的是ActionScript 3.0 (RIP...),因此从零实现一个流体模拟器对我是个极具诱惑力的念头。
但是,第一次python的血汗史让我意识到,这事儿终究不能一蹴而就。想要实现一套拿得出去的方案,需要耐得住性子。
以及一台带GPU的电脑...
于是我就开心地下单了...
可能是因为没了面试的压力,可以更加专注了,这次我花了很大功夫做准备工作,包括:
翻了一遍线性代数...学了一遍OpenGL基本知识。推荐这个网站:Learn OpenGL, extensive tutorial resource for learning Modern OpenGL。一开始的话看完Getting Started就足够了。搭好了particle system(就是个数组,记录粒子的位置速度等信息...),又写(chɑo)了一个camera,用来360度无死角的监视这些粒子。camera是我认为的学习CG的一个很好的入口,可以将坐标系、线性变换的知识应用起来。推荐一本书:3D Computer Graphics: A Mathematical Introduction with OpenGL: Samuel R. Buss。有兴趣的话搜书名就好...
前期准备工作基本就这些了。第一遍我写的仍是基于CPU的算法。目的是以后写GPU遇到bug时好歹有个参考,前提是对于CPU版本是正确的这点要有蜜汁自信...后来运行下看了看,感觉像是对的(粒子没炸),但还是很慢。
写CUDA时还需要几点微小的工作:
学习了一个GPU的基本(suɑn)法。这里推荐一门课:Udacity CS344: Intro to Parallel Programming。这课又学CUDA又学并行算法,帅爆了有木有?在用CUDA写完整套算法后,我没能找到按下F5的勇气,于是又写了几个单元测试。实证明,这些测试就像TLA+一样,它不能保证100%的正确性,但是能给你99%的信心。
最终第一次按下F5后,效果是这样的:
https://www.zhihu.com/video/989525393724022784
开心到炸
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|