話說我最近終於一咬牙,花了一個月工資,買了塊史上最強網卡:GTX670。此卡在手,心癢難忍,必須要寫個demo來測一下網速,考慮了半天,決定來實現一下基於Curl Noise的流體模擬.
這種流體模擬並不是基於物理的,其基本思想就是生成一個隨機的速度場來控制粒子的運動。但是為了保證視覺上可信,還是需要滿足不可壓縮流的基本條件:這個隨機的速度場需要是無源場(divergence-free),即散度處處為0。
那么現在的問題是,怎么生成一個散度處處為0的速度場呢?注意到有這樣一個微分恆等式:div(curl(Φ)) = 0,也即是說,旋度場的散度為0。該恆等式的滿足需要Φ有連續的二階混合偏導。於是我們可以先生成一個二階導連續的場Ψ, 再求出它的旋度場Φ,然后用Φ做為速度場,就自然的滿足不可壓縮條件了。而Ψ的生成因為沒有太多限制,顯然容易多了,比如可以使用改進的perlin noise(5次樣條的那個)。我使用的是simplex noise, 盡管原則上來說他並不滿足上面那個微分恆等式,但看起來也還ok.
在實際應用中未必真的需要生成一張3D的噪聲場, 可以參照這篇文章做一些簡化,這樣只需要一張2D的噪聲紋理就夠了。
另外smash大神的這篇文章也很值得一看,我基本上就是照着他做的,只是他說的bitonic sort會打亂已排序粒子的順序,因此不適合做成progressive的, 所以我改用了CLRS上的那個排序網絡。
程序在這里...
源碼在這里...
截圖在下面...