How to distort graphics in a wave-like way?

I saw a certain graphics distortion effect on multiple games over time and am interested in doing it in 2D. It is like a wave-like texture distortion, I am not entirely sure what it is called actually. Super Mario 64 had an effect like that when you enter a painting depending on your position (https://www.youtube.com/watch?v=H6r5oF73gNI#t=72), also Braid has one which is even more similar to that what I am trying to achieve when you use the time ring (https://www.youtube.com/watch?v=uqtSKkyJgFM#t=38).

I would really like to know how those effects were implement and if there is support for something like that in LWJGL (or even Slick2D). So far, I found absolutely nothing explaining on how it was done.

• 2 ideas come to mind: A shader, or an animated object. The latter is most likely in older games, but the first will be better in modern games.
– user39686
Feb 28, 2015 at 16:14
• @Thebluefish Hmm.. shader seems logical. Any idea how that would work in LWJGL? Feb 28, 2015 at 16:50
• A quick random search gives a few tutorials on this topic Feb 28, 2015 at 17:28

The Mario64 effect is done by moving vertices.

You need a grid for fluid quantity (a water level height value) represented by the black dots height. And a grid of direction & speed of transfer between the former grid's cells which simulates water's inertia (the red arrows).

Every simulation tick each height cell tries to return to 0 by pushing out or sucking in water to/from its neighbors, this is added to the transfer movement values at the cell boundaries, friction is applied to this, then these transfer movement values are applied to every height cell.

Friction is approximated by speed = speed * (1 - tiny_value)

Inertia is approximated by speed = speed + (push * small_value)

Due to rounding errors ""water"" will be lost or gained overall so a very small correction toward height=0 should also be applied every N frames to help the simulation come to rest if a state of rest is required.

If one cell (vertex) is to be pushed down (ie: by -4) then all neighbors must be pushed up by an equal total amount (left, right, up, and down: each by +1).

To cause the initial impulse you don't push down the cell, you set its transfers to transfer height away from it, then height gets transfered away at that stage of the simulation.

• Thanks for your reply. This answers how to calculate the heights at which parts of the texture need to be rendered, but I still dont know hot render parts of the texture at different heights. Is there any pre-defined shader or similar for this? Feb 28, 2015 at 17:54
• @1337 by rendering lots of quads, and giving each quad a different part of the texture? Mar 1, 2015 at 2:24
• @immibis That sounds like a goos idea. Do you know any explanations in jow to implementiert this? Also, how to handle multiple 'wave sources' at once? Mar 1, 2015 at 9:59
• @immibis Sorry for the typos, just noticed, meant to write "good" and "how".. mobile. Is there anyhting like a recomennded quad size? I probably cant do it for every pixel.. Mar 1, 2015 at 11:22