fps
Use device orientation, mouse, qwe-keys to navigate.
Fractal + spline based procedural world (~20kb in public domain). 3D WebGL model. 60 fps on Nexus 10. Sorry the script uses OES_element_index_uint extension and doesn't work on Mali 400 or Tegra 4.
The World with antialiasing is more smooth, but too heavy for mobile yet.

Spline based and Fractal terrains

Tensor product subdivision spline patches

Tensor product of cubic subdivision spline curves is used to make 2D spline patches (random splined terrains). At first an array hi, j of random heights (control points) is generated on regular square grid (see below). Then subdivision and averaging steps are used repeatedly.
| | |
—   hi, j   —   hi+½, j   —   hi+1, j   —
| | |
—   hi, j+½   —   hi+½, j+½   —   hi+1, j+½   —
| | |
—   hi, j+1   —   hi+½, j+1   —   hi+1, j+1   —
| | |
Subdivision step for every old (hi, j , hi+1, j , hi, j+1 , hi+1, j+1 ) quad:
    hi+½, j = (hi, j + hi+1, j )/2,
    hi, j+½ = (hi, j + hi, j+1 )/2,
    hi+½, j+½ = (hi, j + hi+1, j + hi, j+1 + hi+1, j+1 )/4.

Averaging step for all sites of the new lattice:
    hi+½, j+½ = (4 hi+½, j+½ + 2 (hi+½, j + hi+½, j+1 + hi, j+½ + hi+1, j+½ ) +
        hi, j + hi, j+1 + hi, j+½ + hi+1, j+½ ) / 16.

See Spline based terrain. Procedural 2D smooth noise texture. Compare it with the procedural Fractal texture.

The codes are small enough

 var k = 512,  m = 32,  c16 = 1/16;
 var h = new Float32Array(k*k), hb = new Float32Array(k*k);
 var mm = m*m, mm1 = mm - 1,  m1 = m - 1;
 for(var i = 0; i < mm; i++ ) h[i] = z0*rand();
 while(m < k){
   for(var j = 0; j < mm; j += m ){  //  subdivision
    var jp = (j + m) & mm1;
    for(var i = 0; i < m; i++ ){
      var ip = (i + 1) & m1;
      var t = i+j,  m2 = m + m;
      var h0 = h[t], h1 = h[ip+j], h2 = h[i+jp];
      t = 2*(i + 2*j);
      hb[t] = h0;
      hb[t + m2 + 1] = (h0 + h1 + h2 + h[ip+jp])*.25;
      hb[t + 1] = (h0 + h1)*.5;
      hb[t + m2] = (h0 + h2)*.5;}}
   m = m2;
   mm = m*m;  mm1 = mm - 1;  m1 = m - 1;
   for(var j = 0; j < mm; j += m ){  // averaging
    var jp = (j + m) & mm1,  jm = (j + mm - m) & mm1;
    for(var i = 0; i < m; i++ ){
      var ip = (i + 1) & m1,  im = (i + m - 1) & m1,  t = i + j;
      h[t] = c16*(4*hb[t] +
        2*(hb[ip + j] + hb[im + j] + hb[i + jp] + hb[i + jm]) +
        hb[ip + jp] + hb[ip + jm] + hb[im + jp] + hb[im + jm]);}}
 }

Fractal terrains

To get random multi-scale noise (see Fractal terrains) by the diamond square algorithm we use random disturbation (instead of avereging) of the new points in every subdivision step as
    hi+½, j = (hi, j + hi+1, j )/2 + a Random(),
    hi, j+½ = (hi, j + hi, j+1 )/2 + a Random(),
    hi+½, j+½ = (hi, j + hi+1, j + hi, j+1 + hi+1, j+1 )/4 + a Random()
    a = a / 2.

Therefore we can combine random disturbation and smoothing to get complex random procedural mixed terrains (see also 2048×2048 world at the top of the page). "Red planet". Lake with 1250 procedural plants, lake with complex plants and lake editor.

Terrain editor

A simple Terrain editor.
Contents     updated 26 Aug 2014