Pygame水波纹效果

发布于 2024-12-07 17:11:40 字数 1005 浏览 1 评论 0原文

我已经用 Google 搜索过它,但没有现成的脚本 - 与 Flash 上的相同效果相反。我已经检查了 水效应解释 并测试了 Perlin Noise,它可以很好地模拟平坦表面上的波浪末端。我正在寻找基于鼠标悬停/悬停操作的几个 Flash Effects 上的相同实现。这是针对交互式楼层库,我希望在这个问题上远离 Flash,特别是为了避免如此简单的代码逆向工程 - 是的,我知道它可以只使用一些现成的 Flash 代码,但我只会将其作为最后的手段。

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

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

这里的罪魁祸首是传递值列表的(代码)接口通过 Python 从外部解释器(跟踪器 - 但不是 TUIO)发送。我已经尝试了好几天,但 Pygame 无法像纯粹的 C/C++ 代码(如用于 OpenGL 中的着色器)一样快地生成任何内容,而且我对 C/C++ 的了解为零。因此,我们的目标是至少从 Python 代码中获得这些内容。

一个很好的例子,与 Flash 效果不同,但仍然很好,使用 Java applet 进行水模拟< /a>.

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

I have Googled for it but there are no ready scripts - as opposed to the same effect on Flash. I have checked the algorithm on The Water Effect Explained and also tested an implementation of the Perlin Noise, which provides a good simulation of the end of waves on a flat surface. I am looking for the same implementation found on several Flash Effects, based on mouseover/hover actions. This is targetting an interactive floor library, and I would enjoy moving away from Flash for this matter, particularly to avoid such easy reverse-engineering of the code - and yes, I know it could just use some ready-made flash code, but I would only use that as a last resort.

Has anyone seen a suitable implementation of this effect for Pygame (using OpenGL or not)?

EDIT: Can anyone provide a suitable implementation of this effect using OpenCV/OpenGL and Pygame?

The culprit here is the (code) interface to pass a list of values that will be sent from an external interpreter (tracker - not TUIO though) via Python. I have tried for some straight days but Pygame is not able to generate anything as fast as sheer C/C++ code (as used for the shaders in OpenGL), and my knowledge of C/C++ is null. So the target is to at least have that coming from Python code.

A good example, different from the Flash effect but that is still good is Water Simulation using Java applet.

(bounty is showing answers do not have enough detail since this was the closest to 'the OP is incapable of creating the code he wants to as he lacks fundamental skills and this answer will probably be of use to several people').

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

猫卆 2024-12-14 17:11:40

在做完作业(又名研究)并尝试将问题上发布的 Java 代码参考直接转换为 Python 后,在尝试让 Python/Numpy 根据像素颜色的位置更新巨大的像素颜色数组时,经历了非常非常悲伤的经历涟漪效应的涟漪(抱歉,我的第一语言不是英语),因此为每次效果计算解析几个 (x,y) 位置并将其传输到屏幕上的显示表面上(随后出现 surfarray),我得出的结论 - 这得到了其他评论者的支持 - Pygame 根本不会足够强大来实际遍历整个像素数组并将计算结果应用到图像上的每个像素上屏幕速率至少为 24 fps(低于平均水平的体验)。

引用 Last Light Productions 和前 Project Geometrian,Ian Mallet:

PyGame 不太适合像素推送。除了 GPU 之外,什么都不是。

然后搜索结果是搜索 Alkahest - 结果永远不会真正找到了 - 并且基于波纹图像的相同想法,但这次通过使用透明度 Pygame 表面的几层,我发布了问题Gamedev 上的 Pygame 循环裁剪/掩码选择的答案实际上证实了我已经担心 Pygame 永远不会的事实要有足够的男子气概来胜任这份工作。

一天后,我回到之前的开发想法,遇到了Ogre3D。事实证明,(1) Ogre3D 和示例是开源的,(2) 其中一个示例是与移动物体交互的 3-D 水模型,这与我尝试在 2-D 中实现的效果完全相同,但是以更专业的方式。

由于我对 C/C++ 的了解为零,所以我决定询问如何自定义 Ogre3D 水演示 想要了解从哪里开始寻找,其中一个答案向我指出了 Touchscape 提供的软件,其中提供了 SDK(请参阅 这个答案)。

Ogre3D 几乎把它包起来了。水波纹效果、OpenGL(可以可选根据硬件使用)、游戏引擎和 Python通过 Python-Ogre 进行包装 - 所以我对自己问题的回答,

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

基本上是

是的。查看随 SDK 提供的 Ogre3D 水演示 - 并通过 Python-Ogre 将其插入 Python。< /p>

After doing homework (a.k.a. research) and trying to directly convert the Java code reference posted on the question into Python, and having a very, very sad experience while trying to have Python/Numpy update a humongous array of pixel colors based on their positions for the rippling of the ripple effect (sorry, my first language isn't English), thus parsing several (x,y) positions for each pass of the effect calculations and blitting that onto the displayed surface on the screen (surfarray ensues), I've come to the conclusion - that is backed up by other commenters - that Pygame simply won't be powerful enough to actually traverse that entire array of pixels and apply results of calculations onto every pixel on the screen at a minimum rate of 24 fps (for a less-than-average experience).

Quoting the very developer behind Last Light Productions and the former Project Geometrian, Ian Mallet:

PyGame is not so good for pixel pushing. Nothing is, other than the GPU.

The search then turned out to be a search for Alkahest - something that would turn out never to be truly found - and based on the same idea of rippling images, but this time by using transparency to see through several layers of Pygame surfaces, I posted the question Pygame circular cropping/masks on Gamedev. The chosen answer actually corroborates the fact I already feared that Pygame would never be macho enough for the job.

One day later I went back to my previous ideas on development and came across Ogre3D. It turns out that (1) Ogre3D and samples are open-source and (2) one of the examples is a 3-D water model that interacts with a moving object, exactly the same thing I tried to achieve in 2-D, but in a much more professional manner.

Since my knowledge in C/C++ is nil, I decided to ask about how to customize the Ogre3D water demo for a glimpse of where to start looking, and one of the answers pointed me to software from Touchscape where an SDK is provided (see this answer).

Ogre3D pretty much wrapped it up. Water ripple effect, OpenGL (which it may optionally use based on hardware), Game Engine and Python wrappers via Python-Ogre - so my answer to my own question,

Can anyone provide a suitable implementation of this effect using OpenCV/OpenGL and Pygame?

is basically

Yes. Check Ogre3D's water demo, provided with the SDK - and plug it into Python via Python-Ogre.

夜空下最亮的亮点 2024-12-14 17:11:40

以下使用 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)

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) # 

The following using numpy might get you started. It should be fast enough as it is though you could get much faster even in python (have a look here to see how http://www.scipy.org/PerformancePython).

By the way there are several drawbacks in the method described :

  1. you cannot control the speed of the ripples - to do that you would have to modify the equations used in the ripple function (if you figure out how it relates to the wave equation http://en.wikipedia.org/wiki/Wave_equation then you are done)
  2. the "depth" of the "pool" is fixed (and probably too shallow). I added a depth parameter to magnify the effect
  3. the article reads integer pixel offsets - you would get a much nicer result with interpolated values (i guess you can do that with opengl, but my knowledge in that area is nil)

code:

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 and y should be grids from a numpy.meshgrid call : here's a sample usage:

    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) # 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文