2011-10-04 77 views
32

我已經使用谷歌搜索,但沒有現成的腳本 - 而不是相同的Flash效果。我已經檢查了The Water Effect Explained上的算法,並且還測試了Perlin Noise的實現,該實現可以很好地模擬平坦表面上的波浪末端。我正在尋找基於鼠標懸停/懸停操作的幾個Flash效果中找到的相同實現。這是針對一個交互式樓層庫,我很樂意從這個問題擺脫Flash,特別是爲了避免這種簡單的代碼逆向工程 - 是的,我知道它可以使用一些現成的Flash代碼,但我只會用作最後的手段。Pygame水漣漪效應

有沒有人見過Pygame的這個效果的合適實現(使用OpenGL或不)?

編輯:任何人都可以使用OpenCV/OpenGL和Pygame提供這種效果的合適實現嗎?

這裏的元兇是(代碼)接口,用於傳遞將通過Python從外部解釋器(跟蹤器 - 不是TUIO)發送的值列表。我已經嘗試了幾天,但Pygame無法像純C/C++代碼(用於OpenGL中的着色器)那樣快速生成任何東西,並且我對C/C++的知識爲空。所以目標至少是來自Python代碼。

一個很好的例子,與Flash效果不同,但仍然不錯,它是Water Simulation using Java applet

(賞金顯示的答案沒有足夠的細節,因爲這是最接近'OP是不能創建他想要的代碼,因爲他缺乏基本技能,這個答案可能會對幾個人有用') 。

+1

這是你想要的它像工作? http://flash-effects.com/tutorial-create-a-water-ripple-mouse-follow/ – misha

+0

正是 - 如果這是可以實現的,當然我可以繼續在調整 – leon

+1

可能也想嘗試gamedev.stackexchange。 com,在那裏可能會有更好的運氣。 – Davy8

回答

8

d後作業(a.k.a.研究),並試圖直接將問題中發佈的Java代碼引用轉換爲Python,並且在嘗試讓Python/Numpy根據其紋理的位置更新一個龐大的像素顏色陣列時產生非常非常悲傷的體驗效果(對不起,我的第一語言不是英語),因此解析了效果計算的每個過程中的幾個(x,y)位置,並將其顯示到屏幕上顯示的表面上(surfarray發生),我來到結論 - 由其他評論者支持 - Pygame只是不會足夠強大,足以實際遍歷整個像素陣列,並以24 fps的最小速率將計算結果應用於屏幕上的每個像素(對於低於平均水平的經驗)。

報價背後Last Light Productions和前Project Geometrian,伊恩·馬利特非常開發商:

pygame的是不是像素推這麼好。沒有什麼是,除了GPU。

然後竟然是爲Alkahest一個搜索的搜索 - 這會變成永遠不會被真正發現 - 通過基於盪漾的圖像同樣的想法,但這次使用的透明度看Pygame的幾層表面,我在Gamedev上發佈了Pygame circular cropping/masks這個問題。 chosen answer實際上證實了我已經擔心Pygame永遠不會成爲工作的男性

一天後我回到我以前的發展思路和跨Ogre3D來了。事實證明:(1)Ogre3D和樣本是開源的;(2)其中一個例子是一個與移動對象相互作用的3D水模型,這與我試圖在2D中實現的完全相同,但以更專業的方式。由於我在C/C++中的知識爲零,因此我決定詢問how to customize the Ogre3D water demo以瞭解從哪裏開始尋找,其中一個答案指向了Touchscape中提供SDK的軟件(請參閱this answer)。

Ogre3D幾乎將它包裹起來。水波紋效果,OpenGL的(它可以基於硬件optionally使用),通過Python-Ogre遊戲引擎和Python包裝 - 所以我的答案我自己的問題,

誰能提供一個合適的實現使用OpenCV的這種效果/ OpenGL和Pygame?

基本上

是。檢查隨SDK提供的Ogre3D的水演示 - 並通過Python-Ogre將其插入Python。

5

以下使用numpy可能會讓您開始。它應該足夠快,儘管你可以在Python中獲得更快的速度(請看這裏看看http://www.scipy.org/PerformancePython)。

順便說有幾個缺點中描述的方法:

  1. 你無法控制的漣漪的速度 - 這樣做,你將不得不修改紋波函數中使用的等式(如果你的身影然後你就完成了)
  2. 「池」的「深度」是固定的(可能太淺)。我添加了一個深度參數來放大效果
  3. 該文章讀取整數像素偏移量 - 你會得到一個更好的結果與插值(我想你可以用opengl做到這一點,但我在該領域的知識爲零)

代碼:

import numpy 

def ripple(w1, w2, damp, n = 1): 
    for _ in xrange(n): 
     w2 *= -2 
     w2[1:-1,1:-1] += w1[0:-2, 1: -1] 
     w2[1:-1,1:-1] += w1[2: , 1: -1] 
     w2[1:-1,1:-1] += w1[1:-1, 0: -2] 
     w2[1:-1,1:-1] += w1[1:-1, 2: ] 
     w2 *= .5 * (1. - 1./damp) 
     w1, w2 = w2, w1 

def refract(x, y, w, rindex, depth = 10): 
    sx = x[0,1] - x[0,0] 
    sy = y[1,0] - y[0,0] 

    dw_dx = (w[2: ,1:-1] - w[:-2,1:-1])/sx * .5 
    dw_dy = (w[1:-1,2: ] - w[1:-1,:-2])/sy * .5 

    xang = numpy.arctan(dw_dx) 
    xrefract = numpy.arcsin(sin(xang)/rindex) 
    dx = numpy.tan(xrefract) * dw_dx * depth 

    yang = numpy.arctan(dw_dy) 
    yrefract = numpy.arcsin(sin(yang)/rindex) 
    dy = numpy.tan(yrefract) * dw_dy * depth 

    dx *= numpy.sign(dw_dx) 
    dy *= numpy.sign(dw_dy) 

    xmin = x[0,0] 
    xmax = x[0,-1] 
    x[1:-1,1:-1] += dx 
    x[:,:] = numpy.where(x < xmin, xmin, x) 
    x[:,:] = numpy.where(x > xmax, xmax, x) 

    ymin = y[0,0] 
    ymax = y[-1,0] 
    y[1:-1,1:-1] += dy 
    y[:,:] = numpy.where(y < ymin, ymin, y) 
    y[:,:] = numpy.where(y > ymax, ymax, y) 

x和y應該從numpy.meshgrid呼叫格:這裏是一個示例用法:

x,y = meshgrid(x,y) 
    w = 10 * exp(- (x*x + y*y)) 
    w1 = w.copy() 
    x1,y1 = meshgrid(r_[0:len(x):1.0], r_[0:len(y):1.0]) 
    ripple(w, w1, 16) # w1 will be modified 
    refract(x1, y1, w1, rindex=2, depth=10) # x1 and y1 will be modified 
    numpy.around(x1, out=x1) # but you will get better results with interpolate 
    numpy.around(y1, out=y1) #