Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Live Wallpaper Water Ripple Effect

I'm working on a live wallpaper that incorporates some water ripple effects on touching the screen but I'm a little stuck.

Would it be better to create multiple images and loop through them to create a ripple animation or would it be better to distort the bitmap a bit before I place it on the canvas?

This is a video of a very nice ripple effect done through OpenGL.

I don't have any experience yet with OpenGL and was wondering if it is still possible to create a 2D water effect on the live wallpaper?

like image 320
Gatekeeper Avatar asked Apr 26 '12 01:04

Gatekeeper


3 Answers

I wanted to implemented a realistic ripple effect in Android too, so will share my experience:

As a reference implementation i took Sergey's Chikuyonok JavaScript port of Neil Wallis Java algo. Here's a playground where you can experiment with original JS code: http://jsfiddle.net/esteewhy/5Ht3b/6/

At first, i've ported JS code to Java only to realize that there's no way to squeeze more than 1 fps on my Huawei U8100 hardware. (There're several similar attempts on the net with the only conclusion: they're ridiculously slow).

BTW, this SO answer was quite useful to get basic understanding of how to code an interactive graphics in Android: https://stackoverflow.com/a/4946893/35438. I've borrowed fps counter from there.

Then i decided to try Android NDK to reimplement original algo in pure C (my first encounter with it in 10+ yrs!). Despite NDK's docs being somewhat confusing (especially as to requirements and prerequisites), it all worked like a charm, so i was able to achieve up to 30 fps -- it might not be too impressive, but still, a radical improvement over Java code.

Finally, i've put all my work online: https://github.com/esteewhy/whater , so feel free to play with that. It contains:

  1. Interactive bouncing ball code mentioned above (just for the reference).
  2. Water ripples Java port (slow like hell!)
  3. Water ripples C implementation (needs NDK to compile and JDK to create .h file).

(The project is not "clean", i.e.: all binaries are there, so can try to run it "as is" even without NDK.)

enter image description here

like image 78
esteewhy Avatar answered Nov 18 '22 00:11

esteewhy


You can find an example of a touch ripple effect here:

https://github.com/MasDennis/RajawaliExamples

It utilizes the rajawali OpenGL ES framework/library. You can download the rajawali examples app from the market to see how it looks. Browse through the "src" folder and you will see the TouchRippleEffect activity and renderer. Hope that helps.

like image 37
Steve C. Avatar answered Nov 18 '22 01:11

Steve C.


I'm no expert in this, but I believe the typical way to do water effects in OpenGL is with a fragment shader. With a static image as a texture, your shader can vary the texture coordinates used for sampling that image, to distort it in arbitrary ways.

Calculate the pixel's direction and distance from the center of the circle, and adjust the texture coordinate toward or away from the circle's center based on a sinusoidal function of the distance, and you should get a nice ripple effect.

Judging by the description of that YouTube video you linked, it sounds like that's done by using a grid of triangles and adjusting the texture coordinates only at the vertices. That should work too, but it won't look as good unless you use a rather fine grid. Doing it per-pixel with a fragment shader is the ideal, but I don't know whether that would cause performance problems on a phone's GPU.

like image 4
Wyzard Avatar answered Nov 18 '22 01:11

Wyzard