作业8
作业描述
这次作业是固体仿真加渲染,用fem模拟了弹性固体物体自由落体在地面得效果;渲染是通过之前渲染作业得代码做的,最后将仿真及渲染结果合成了视频。
效果展示
渲染结果放到了这里(掉地上感觉太duang了,是不是参数设置的问题,或者网格不够细分…)
代码链接
代码在这里Code
我的大致步骤如下:
1、将原本得斑点牛表面三角形网格结构得模型转化为整体得四面体剖分结构得模型,在网上找了TetGen这个工具来做,先将原本小牛得obj格式文件用blender之类的软件转成stl;
再用TetGen将其转化为mesh格式的文件。
2、使用有限元方式模拟模型物体的自由落体,这里主要参考的作业代码,边界条件为y<=0,正好康纳尔盒子的地板也是y=0;
每一个time step我会生成一份obj,我一共生成了900份obj供后续渲染用;
3、对所有第二步生成的obj循环渲染生成png图片。
4、用python 的cv2模块将所有图片合成视频,其中根据模拟时time step 为16.7ms得出大概一秒会有60(为了加快渲染可以调整下timestep)张图片;
过程中遇到的难点及问题:
1、由于对四面体网格划分相关理论技术没有涉猎,查了很久才找到相关工具;然后有限元模拟自由落体部分很顺利;
2、对于表面三角形网格顶点法线的同步计算被困扰了很久,最开始按我的理解,顶点法线的变化更新应该和顶点相关的,共用同一份deformation gradient,
所以有根据其次坐标空间中的向量变换将3x3的F扩展成4x4矩阵然后叉乘原法线得出新法线;但是实际结果却不对,也搞不懂原因就只能找别的办法;
最后从顶点法向量的生成的角度解决了此问题,在每次time step完成更新过模型的数据后,再重新计算一下表面顶点的法向量,
即每个点的法向量等于模型表面上所有共用此点的所有三角形的面法向量与各个面的面积所占比例的加权求和(好像这种还比原来的效率更高)。最终解决了此问题
3、在渲染时发现我台式机每渲染7张图片就报错(笔记本不报错,但是发现渲染出来每60多张图片都一样)报错信息就是
论坛搜了下发现说是在kernel内定义field导致的,但是看报错的堆栈是在python作用域报的,是我的Scene类,在每次渲染时都要定义一遍模型相关的数据field最后导致的,但是这些定义每次也是不能避免的,因为每次的模型不一样,都要更新所有的bvh模型数据啥的,感觉似乎每次定义的field分配的显卡内存没有释放,执行多次后就不够了?不知道有没有什么解决办法;(所以几百张图片每渲染7张我就手动重新执行下程序,断断续续基本花了1天才渲染完)
4、发现循环给field赋值会很慢,用from_numpy的方式会更快一些;比如我有个100万长度的n=3的向量,循环赋值的时候我电脑要100多秒,然后用from_numpy就1m内就可以了。
最后,之前禹鹏老师说渲染的再优化下可以作为大作业了,那这个可以作为大作业吧,可以的话先拿这个保个底,后面学习流体的仿真渲染如果顺利的话再换;
对了上面说的报错信息如下:
[E 12/06/21 17:52:24.281 9688] [snode_tree_buffer_manager.cpp:taichi::lang::SNodeTreeBufferManager::allocate@44] LLVM backend supports up to 32 snode trees
***********************************
* Taichi Compiler Stack Traceback *
***********************************
0x7ffe9a7ecb4a: taichi::print_traceback in taichi_core.pyd
0x7ffe9a6bc1a9: PyInit_taichi_core in taichi_core.pyd
0x7ffe9a7e4782: taichi::create_instance_unique_ctor<taichi::Task> in taichi_core.pyd
0x7ffe9a75494f: PyInit_taichi_core in taichi_core.pyd
0x7ffe9a756e23: PyInit_taichi_core in taichi_core.pyd
0x7ffe9a78689f: PyInit_taichi_core in taichi_core.pyd
0x7ffe9a5f880b: PyInit_taichi_core in taichi_core.pyd
0x7ffe9a57cdb6: PyInit_taichi_core in taichi_core.pyd
0x7ffe9a54715f: pybind11::error_already_set::discard_as_unraisable in taichi_core.pyd
0x6879b055: PyCFunction_FastCallDict in python36.dll
0x6879bae3: PyObject_GenericGetAttr in python36.dll
0x6879d3ff: PyEval_EvalFrameDefault in python36.dll
0x687991f6: PyErr_Occurred in python36.dll
0x6879bf5b: PyObject_GenericGetAttr in python36.dll
0x6879d3ff: PyEval_EvalFrameDefault in python36.dll
0x6879bcbe: PyObject_GenericGetAttr in python36.dll
0x6879d3ff: PyEval_EvalFrameDefault in python36.dll
0x6879bcbe: PyObject_GenericGetAttr in python36.dll
0x6879d3ff: PyEval_EvalFrameDefault in python36.dll
0x6879bcbe: PyObject_GenericGetAttr in python36.dll
0x6879d3ff: PyEval_EvalFrameDefault in python36.dll
0x687991f6: PyErr_Occurred in python36.dll
0x687cc30a: PyUnicode_Compare in python36.dll
0x6879fa10: PyEval_EvalFrameDefault in python36.dll
0x687991f6: PyErr_Occurred in python36.dll
0x6879783e: PyFunction_FastCallDict in python36.dll
0x68797625: PyObject_Hash in python36.dll
0x6878d11b: PyList_New in python36.dll
0x6878ce9c: PySequence_Fast in python36.dll
0x6879e946: PyEval_EvalFrameDefault in python36.dll
0x6879bcbe: PyObject_GenericGetAttr in python36.dll
0x6879d3ff: PyEval_EvalFrameDefault in python36.dll
0x6879bcbe: PyObject_GenericGetAttr in python36.dll
0x6879d3ff: PyEval_EvalFrameDefault in python36.dll
0x6879bcbe: PyObject_GenericGetAttr in python36.dll
0x6879d3ff: PyEval_EvalFrameDefault in python36.dll
0x687991f6: PyErr_Occurred in python36.dll
0x6878392e: PyEval_EvalCodeEx in python36.dll
0x68783899: PyEval_EvalCode in python36.dll
0x68783843: PyArena_Free in python36.dll
0x68912e19: PyRun_FileExFlags in python36.dll
0x68913555: PyRun_SimpleFileExFlags in python36.dll
0x68912cf7: PyRun_AnyFileExFlags in python36.dll
0x68864d1c: Py_hashtable_size in python36.dll
0x687f9fba: Py_FatalError in python36.dll
0x1c8a126d: Unknown Function in python.exe
0x7ffef23f84d4: BaseThreadInitThunk in KERNEL32.DLL
0x7ffef3b5e871: RtlUserThreadStart in ntdll.dll
Internal error occurred. Check out this page for possible solutions:
https://docs.taichi.graphics/lang/articles/misc/install
Traceback (most recent call last):
File "D:/workspace/CG/taichi/fem_hw/fem_main.py", line 300, in <module>
render.rende_image(obj_fname,img_fname)
File "D:\workspace\CG\taichi\fem_hw\render.py", line 156, in rende_image
self.set_moddel(obj_filename)
File "D:\workspace\CG\taichi\fem_hw\render.py", line 133, in set_moddel
self.scene.commit()
File "D:\workspace\CG\taichi\fem_hw\scene.py", line 81, in commit
self.light_num[None] = self._light_num
File "D:\dev_install\Python3_6\lib\site-packages\taichi\lang\util.py", line 207, in wrapped
return func(*args, **kwargs)
File "D:\dev_install\Python3_6\lib\site-packages\taichi\lang\field.py", line 262, in __setitem__
self.initialize_host_accessors()
File "D:\dev_install\Python3_6\lib\site-packages\taichi\lang\field.py", line 204, in initialize_host_accessors
taichi.lang.impl.get_runtime().materialize()
File "D:\dev_install\Python3_6\lib\site-packages\taichi\lang\impl.py", line 322, in materialize
self.materialize_root_fb(not self.materialized)
File "D:\dev_install\Python3_6\lib\site-packages\taichi\lang\impl.py", line 313, in materialize_root_fb
root.finalize()
File "D:\dev_install\Python3_6\lib\site-packages\taichi\snode\fields_builder.py", line 159, in finalize
impl.get_runtime().prog))
RuntimeError: [snode_tree_buffer_manager.cpp:taichi::lang::SNodeTreeBufferManager::allocate@44] LLVM backend supports up to 32 snode trees
Process finished with exit code 1