Just another quick processing sketch.


//Ripple

final int NUM_RIPPLES = 160;
final int MAX_OPACITY = 120;
float diameter = 1;
ARipple[] ripples;

float bobbleOffset = 0.0;
float inc = TWO_PI/20;

void setup(){
  size(600, 400, P3D);
  noFill();
  frameRate(60);

  ripples = new ARipple[NUM_RIPPLES];

  float initalOffset = 0.0;

  for(int i = 0 ; i < NUM_RIPPLES; i++){
    ripples[i] = new ARipple(diameter, sin(initalOffset)*10.0);
    initalOffset = initalOffset + inc;
    diameter+=8;
  }
}

void draw(){
  background(0);
  pointLight(255, 255, 205, width / 2, 0, 190);

  translate(width/2, height/2, 0);
  rotateX(0.5);

  //Draw the ripples
  noFill();
  for(int i = 0 ; i < NUM_RIPPLES; i++){
    ripples[i].draw();
  }

  //Draw the bobbing sphere
  noStroke();
  fill(100, 115, 100, 255);
  pushMatrix();
  translate(0, bobble(), 0);
  sphere(50);
  popMatrix();
}

float bobble(){
  bobbleOffset = bobbleOffset + inc;
  return sin(bobbleOffset)*2.5;
}

class ARipple{

  float diameter;
  float yOffset = 0;

  public ARipple(float diameter, float yOffset){
    this.diameter = diameter;
    this.yOffset = yOffset;
  }

  void draw(){
    stroke(diameter/1.5, diameter*0.7, diameter/2, (diameter < MAX_OPACITY) ? diameter : MAX_OPACITY);
    ellipse(0, yOffset, diameter, diameter);

    diameter++;

    if(diameter > width * 2.15){
      diameter = 10;
    }
  }
}