我想建立一个让用户绘制机翼轮廓的程序,然后对该轮廓周围的空气进行实时模拟。计算将在GPU上完成。
我为这个程序做了一个设计,你可以在这个丑陋的MS Paint绘图中看到:
着色器程序2使用纹理1,它是粒子网格,进行碰撞检测,并将其渲染到纹理2.然后程序1使用更新的网格,计算时间步长,并将其渲染为帧缓冲对象1中的纹理1。然后程序3将此纹理渲染到屏幕上。
我在将信息以不完全停止gpu的方式返回客户端的步骤中迷失了。我唯一想要回来的就是机翼上产生的升力。每当粒子与机翼碰撞时,它就会将动量传递给机翼。我需要一种方法来添加所有那些微小的动量,并在多个帧上计算机翼上的平均力。
答案 0 :(得分:5)
我不相信这个问题非常适合该网站,因为它非常本地化,但仍然过于开放,但让我无论如何都要通过它,因为GPU加速流体模拟是我的高级项目,让我们面对它,这真的很有趣。
首先,我建议不要在OpenGL中完成所有这些操作,而是选择OpenCL。它是为一般计算而制作的,因此您可以更轻松地以合理的,特定于域的方式来回获取数据(例如,您不必考虑纹理以及所有特定于图形的爵士乐。
如果您使用OpenGL进行渲染并使用OpenCL进行计算,则可以share some of your buffers避免从上下文到另一个上下文的不必要副本。我将计算OpenCL缓冲区中的所有粒子位置,与OpenGL共享该缓冲区并使用geometry shader发出构成流体渲染的图形基元。
其次,您必须接受从GPU获取数据总是很昂贵。如果你可以避免在主机上需要它,那就这样做吧。否则,你几乎有两个选择:
particle_count
的OpenCL缓冲区中将每个粒子传输的动量写入机翼,将其读入主机内存,然后在CPU上求和。atomic_add
在sizeof(force_type)
大小的缓冲区中对GPU上的机翼上的力进行求和,并将其读入主机内存。选项2可能比选项1更快,或者它可能会更慢,具体取决于从您拥有的粒子数量到图形驱动程序的大量因素,因此您需要进行实验和基准测试(通常是这样做GPGPU时你想做的事情。)
你在两种纹理之间交替的想法是一种非常好的洞察力。它可以让您避免与"剪切相关的问题"数据(一些粒子被更新但有些粒子不是)。您应该始终从单个缓冲区读取并写入另一个缓冲区。当然,这会花费你正在使用的VRAM的数量。
最后,如果您想了解我们在OpenCL中如何亲自完成此操作,请查看libclsph
。请记住,它根本不是生产准备,碰撞系统是一个可怕的近似(充其量),它表明它是一个学生项目。它还面向图形和外部渲染器,因此我们将粒子写入文件,我们不会计算环境的力量。然而,它是一个很好的开始例子,说明如何在OpenCL中进行流体模拟。
如果您需要更多信息并祝您好运,请告诉我。有很多事情要考虑,但这是一个很酷的项目!