物理动画流体实现流程(Physically Based Fluid Animation)

0 说在开始

发现介绍物理动画实现流程的文章较少,入门需要一定时间,所以才有了这篇文章。此文章不具体介绍算法部分和数学公式,例如SPH、欧拉公式、NS公式、弹簧质点模型等等,而是如何去构造自己的第一个计算机图形学动画,其中涉及较多Reference,我会在文章最后给出,非常感谢。(其为我在实验室做实验时整理得到,趁热记录~)

作者:憨豆酒(YinDou),联系我[email protected],熟悉计算机图形学领域。因个人实验室的代码不方便开源,找到代替代码,流程都是类似的:可在此仓库中找到:https://github.com/douysu/person-summary,所有代码都是在Ubuntu 18.04.4 LTS完成,如果对您有帮助,还请给一个star,如果大家发现错误以及不合理之处,还希望多多指出。

我的知乎

我的Github

我的博客

所需知识、内容和工具:

  • OpenGL-实时可视化运行状态. 链接
  • 图形学物理仿真知识扫盲-闫令琪Animation图形课程部分. 链接
  • Blender、Mitsuba Renderer或其他渲染器. 链接

1 运行结果

2 物理动画渲染流程

其可以分为三步:

(1)物理仿真:其包括多种算法,基于粒子的物理方法。赋予粒子物理特性,例如重力,张力,相互作用力,计算粒子下一步位置。

(2)液体表面重建:无论欧拉方法还是拉格朗日方法,粒子都是离散的,都先需要进行液体表面重建,计算法向量,然后在送入Blender进行渲染。 链接

(3)离线渲染:在Blender中设置场景(光照、材质、摄像机)中渲染成图像。使用工具将连续图像序列转为视频。

一步步来介绍。

3 物理仿真

使用WCSPH、PCISPH、DFSPH或者其他物理仿真算法实现仿真,可视化部分使用OpenGL,如以下几个开头效果的仿真图,算法实现部分和场景搭建可以查看其它Github和文章。

物理动画流体实现流程(Physically Based Fluid Animation)_第1张图片

物理动画流体实现流程(Physically Based Fluid Animation)_第2张图片

在仿真过程中,记录每一帧的粒子信息到二进制文件中,这里二进制的文件格式为.pos。如下。这里需要注意,重构时,不同相的物体需要分开保存,因为渲染阶段需要付给物体不同材质。例如,这里的0_0_d.pos为第一帧水杯,需要付给玻璃材质。0_0_f.pos对应流体的内容,也就是杯子中的水,需要付给水材质。

物理动画流体实现流程(Physically Based Fluid Animation)_第3张图片

有了每一帧粒子的数据了,下一步为重构。

4 液体表面重建

得到每一帧.pos二进制文件,对每一帧中的所有.pos进行重构得到ply模型。这里对应331帧和332帧ply。

物理动画流体实现流程(Physically Based Fluid Animation)_第4张图片

5 离线渲染

打开Blender,导入ply,设置场景(材质、灯光、视角、背景板等)点击渲染->渲染图像。渲染当前帧图像。

物理动画流体实现流程(Physically Based Fluid Animation)_第5张图片

只是一帧渲染方式,我们有很多帧动画,不可能一帧一帧手动渲染。解决问题,Blender支持脚本编程,可以实现自动渲染,来看脚本,实现200-375帧渲染。water为保存的水材质的名称。

# -*- coding:utf-8 -*-
import shutil
input_path = "K:\\我的资料库\\YD\\IISPH-Three-Despace"
path_ply2 = input_path + "\\pos\\"
path_ply3 = input_path + "\\solid-ply\\"
path_ret = input_path + "\\re2\\"
for n in range(200, 375):
    bpy.ops.import_mesh.ply(filepath=path_ply2 + str(n) + "_c.ply")
    bpy.context.object.active_material=bpy.data.materials["water"]
    bpy.ops.import_mesh.ply(filepath=path_ply2 + str(n) + "_f.ply")
    bpy.context.object.active_material=bpy.data.materials["water"]
    bpy.context.scene.render.filepath = path_ret + str(n) + ".png"
    bpy.ops.render.render(write_still=True)
    bpy.ops.object.delete()
    # remove mesh from memory
    mesh_c = bpy.data.meshes[str(n) + '_c']
    mesh_f = bpy.data.meshes[str(n) + '_f']
    mesh_c.user_clear()
    mesh_f.user_clear()
    bpy.data.meshes.remove(mesh_c)
    bpy.data.meshes.remove(mesh_f)

最后得到200-375连续帧图像,在使用工具转成视频即可。

物理动画流体实现流程(Physically Based Fluid Animation)_第6张图片

Reference

  • GAMES101-现代计算机图形学入门-闫令琪
  • GAMES201:高级物理引擎实战指南2020 胡渊鸣
  • Blender渲染引擎Cycles教程
  • Fluid Engine Dev - Jet
  • 液体渲染:一种屏幕空间方法
  • 以及本文出现的所有链接

你可能感兴趣的:(3D图形学)