Pygame水波纹效果

leo*_*eon 33 python opengl pygame image-processing effect

我已经谷歌搜索它,但没有准备好的脚本 - 而不是对Flash的相同效果.我已经检查了水效应解释的算法,并测试了Perlin噪声的实现,它可以很好地模拟平面上的波浪末端.我正在寻找基于鼠标悬停/悬停操作在几个Flash Effects上找到的相同实现.这是针对一个交互式楼层库,我很乐意远离Flash,特别是为了避免代码的这种简单的逆向工程 - 是的,我知道它可以只使用一些现成的flash代码,但我只会用它作为最后的手段.

有没有人为Pygame看过这种效果的合适实现(使用OpenGL与否)?

编辑: 任何人都可以使用OpenCV/OpenGL和Pygame提供这种效果的合适实现吗?

这里的罪魁祸首是(代码)接口传递一个值列表,这些值将通过Python从外部解释器(跟踪器 - 而不是TUIO)发送.我已经尝试了几天,但是Pygame无法像C/C++代码那样快速生成任何东西(用于OpenGL中的着色器),而且我对C/C++的了解也是空的.所以目标至少要来自Python代码.

一个很好的例子,与Flash效果不同,但仍然很好的是使用Java applet的Water Simulation.

(赏金显示答案没有足够的细节,因为这是最接近'OP无法创建他想要的代码,因为他缺乏基本技能,这个答案可能对几个人有用').

leo*_*eon 9

做完作业(又称研究)并尝试将问题上发布的Java代码参考直接转换为Python,并且在尝试让Python/Numpy根据其位置更新大量像素颜色时,有一种非常非常悲伤的体验.涟漪效果的涟漪(对不起,我的第一语言不是英语),因此解析效果计算的每一遍的几个(x,y)位置和blitting到屏幕上显示的表面上(随后是surfarray),I "我是来的结论-那是由其他批评家备份-这pygame的根本不会强大到足以实际穿过像素是整个阵列和屏幕上的应用计算的结果到每一个像素24 fps的最低速率(对于低于平均水平的经验).

引用Last Light Productions和前Project Geometrian背后的开发人员,Ian Mallet:

PyGame对像素推送不太好.除了GPU之外,什么都没有.

然后搜索结果是对Alkahest的搜索- 这将是永远不会真正找到的东西 - 并且基于相同的波纹图像的想法,但这次通过使用透明度来透视几层Pygame表面,我发布了问题Pygame的圆形裁剪/掩模上Gamedev.在选择的答案居然证实我已经担心Pygame的绝不会是这样的事实男子气足够的工作.

一天后,我回到了我之前关于开发的想法并遇到了Ogre3D.事实证明(1)Ogre3D和样本是开源的(2)其中一个例子是与移动物体相互作用的三维水模型,与我试图在二维中实现的完全相同,但是以更专业的方式.

由于我在C/C++方面的知识是零,我决定询问如何自定义Ogre3D水演示以便从一开始就看一下,其中一个答案指向我提供了一个SDK提供的软件(请参阅此内容)回答).

Ogre3D几乎把它包裹起来.水波纹效应,OpenGL(它可以选择使用基于硬件),游戏引擎和Python包装器通过Python-Ogre - 所以我回答我自己的问题,

任何人都可以使用OpenCV/OpenGL和Pygame提供这种效果的合适实现吗?

基本上是

是.查看随SDK提供的Ogre3D的水演示 - 并通过Python-Ogre将其插入Python .


spa*_*ggs 5

以下使用numpy可能会让你开始.它应该足够快,尽管你甚至可以在python中获得更快的速度(看看这里是如何看http://www.scipy.org/PerformancePython).

顺便说一下,所描述的方法有几个缺点:

  1. 你无法控制涟漪的速度 - 要做到这一点,你必须修改涟漪函数中使用的方程式(如果你弄清楚它与波动方程有什么关系http://en.wikipedia.org/wiki/Wave_equation那么你做完了)
  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)
Run Code Online (Sandbox Code Playgroud)

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) # 
Run Code Online (Sandbox Code Playgroud)