## Ripple Effect on the iPhone

March 13, 2010 6 Comments

So on this iPhone App I am working on I am trying to create an effect on a image such that if you touch any part of the image the app will simulate a water ripple effect out from the touch point. After a few hours of research it became clear to me that I would have no choice but to attempt this effect using OpenGL ES which I had been trying to avoid. However I discovered this excellent tutorial complete with project template that made things a lot easier:

http://iphonedevelopment.blogspot.com/2009/05/opengl-es-from-ground-up-table-of.html

Using this tutorial I was able to create my texture map and apply an image to it. From there it just became a matter for coding the ripple effect. Here is what I came up with:

-(void)update:(float)time{ int i; for( i = 0; i < (80*120*6); i++ ) { int index = i * 3; float *vertArray = (float *)originalVertices; Vertex3D v = { vertArray[index], vertArray[index+1], vertArray[index+2] };

CGPoint vect = CGPointMake(position.x - v.x, position.y - v.y); CGFloat r = sqrtf(vect.x*vect.x + vect.y*vect.y); if ( r < radius ) { r = radius - r; CGFloat rate = powf( r / radius, 2); v.z += (sinf( time*(CGFloat)M_PI*waves*2 + r * 0.1f) * amplitude * amplitudeRate * rate );

} float *vertArray2 = (float *)vertices; vertArray2[index] = v.x; vertArray2[index+1] = v.y; vertArray2[index+2] = v.z; } }

I still have a ways to go to finish it but here’s what is going on so far. First I’m looking through all of my vertices in my texture map. My texture map is 80×120 and for each point I am actually am creating 6 vertices to render a square. I know this can be optimized using GL_TRIANGLE_STRIPs but I’m not there yet. Then I create the vector and distance (r) from the touch point.

Assuming I am within the radius of the ripple I defined (which I could make dynamic down the road based on touch time) I then calculate the new depth (z) of the vertex I am on using the amplitude and other values that were set previously. After that I just update the vertices to render with the new values and it’s good to go.

I still have to handle multiple touches and other factors but what I ended up with so far is pretty cool. I’ll post a video of the effect once I’m done.