CGBeginner

 

Introduction to my galaxy engine 8 : Real Time Fluid Rendering

最近正在研究real time fluid effect方面的问题,主要适用于液体,烟雾,火焰方面的实时模拟。一般是通过GPGPU(general purpose GPU)来实现的。

 

以下是2D Fluid初步实验的截图:

要理解实现原理,首先要熟悉其基于的物理模型:“stable fluids” by Stam 1999. 从实现角度来说,根据fluid effect的计算公式

主要考虑如下几个要素:Advection [气]水平对流, pressure, diffusion, (Vorticity [涡旋] Confinement 主要用于烟雾,火焰), external forces. 每一个要素的作用大小是通过读取其对应的图片来获取的。

具体实现步骤如下:

1.将屏幕分为一定大小数量的网格,如图所示:

由于我的窗口大小设定为800*600,横行分为了80*2格,纵向分为了60*2格.之后的相关计算都是以格子为单位。蓝色为边界部分,不做为渲染区域。

2. 根据网格生成顶点。

    VS_INPUT_FLUIDSIM_STRUCT tempVertex1;
    VS_INPUT_FLUIDSIM_STRUCT tempVertex2;
    VS_INPUT_FLUIDSIM_STRUCT tempVertex3;
    VS_INPUT_FLUIDSIM_STRUCT tempVertex4;

    int w = m_dim[0];
    int h = m_dim[1];

    float left   = -1.0f + 2.0f/w;//exclude the boundary cell, each cell size is 2.0f/w
    float right  =  1.0f - 2.0f/w;
    float top    =  1.0f - 2.0f/h;
    float bottom = -1.0f + 2.0f/h;

    tempVertex1.Pos = D3DXVECTOR3( left, top, 0.0f);//projection screen pos
    tempVertex1.Tex = D3DXVECTOR3( 1.0f, 1.0f, 0.0f);//texture pos, exclude boundary cell

    tempVertex2.Pos = D3DXVECTOR3( right, top, 0.0f);
    tempVertex2.Tex = D3DXVECTOR3( (w-1.0f), 1.0f, 0.0f);

    tempVertex3.Pos = D3DXVECTOR3( right, bottom, 0.0f);
    tempVertex3.Tex = D3DXVECTOR3( (w-1.0f), (h-1.0f), 0.0f);

    tempVertex4.Pos = D3DXVECTOR3( left, bottom, 0.0f);
    tempVertex4.Tex = D3DXVECTOR3( 1.0f, (h-1.0f), 0.0f);

    (*vertices)[index++] = tempVertex1;
    (*vertices)[index++] = tempVertex2;
    (*vertices)[index++] = tempVertex3;
    (*vertices)[index++] = tempVertex1;
    (*vertices)[index++] = tempVertex3;
    (*vertices)[index++] = tempVertex4;

3. 生成速度场velocity field。

液体的流动,是由于外力的作用,在这里,力的大小我们通过每一个点的速度大小来度量。屏幕上每一点的速度保存在屏幕大小的一张图片上,如图所示:

由于是2D,所以只有X,Y平面上的速度。X方向的力用红色表示,Y方向的力用绿色表示。颜色深度表示力的大小。需要注意的是此图中只能看到正向方向的力,负向方向力由于图片颜色最小值为0,负值被截去了所以的里看不出来,但实际从render target中是可以读出负值的。

速度场的计算方式有很多种,在这里我用的是gaussian splat,公式如下:

速度场大小是随半径大小成指数递减的,公式中大括号里少了个负号。代码表示为spaltColor = force * exp(-dist / g_Radius);

4. 生成油墨,烟或者火焰。

实现方法类似速度场,不过我稍作了改变,用了这个公式:spaltColor = force * (dist < g_Radius ? 1.0f : 0.0f);

5. Advection.

有了速度场,就可以计算单位时间内油墨的偏移量和速度场自身的偏移量。原理图如下:

u(x,t)点的颜色值用X点的颜色值来更新。两者的距离为u(x,t)乘以单位时间g_TimeStep。

6. Diffustion.迭代计算公式如下:

a = (dx)2/vdt, and b = 4 + a.

v表示速度,为定值。dx此处为1. x表示需要更新的速度值,通过N次迭代计算更新。Diffuse还可作用于颜色上,此时v表示之前的颜色值,X表示更新的颜色值。

7. Vorticity confinement

。。。。。。。。。内容太多,明天继续。。。。。。。。。。。。。。

8. Velocity Divergence.

9. Pressure.

10. Project Velocity

11.static obstacle

References:

[1] GPU Gems, Chapter 38. Fast Fluid Dynamics Simulation on the GPU

[2] GPU Germs, CHAPTER 30. REAL-TIME SIMULATION AND RENDERING OF 3D FLUIDS

[3] 关于Vorticity的介绍 http://www.student.math.uwaterloo.ca/~amat361/Fluid%20Mechanics/topics/vorticity.htm

[4] NVIDA SDK http://developer.nvidia.com/gpu-computing-sdk

posted on 2012-06-11 14:36  CGBeginner  阅读(724)  评论(0编辑  收藏  举报

导航