Skip to main content
Code snippet was out of alignment.
Source Link
Ivan
  • 187
  • 6
            if ( ! Detector.webgl ) {

                Detector.addGetWebGLMessage();
                document.getElementById( 'container' ).innerHTML = "";

            }

            var fogExp2 = true;

            var container, stats;

            var camera, controls, scene, renderer;

            var mesh, mat;

            var worldWidth = 200,
  worldDepth = 200,
            worldHalfWidth = worldWidth / 2,
  worldHalfDepth = worldDepth / 2,
            data = generateHeight( worldWidth, worldDepth );

            var clock = new THREE.Clock();

            init();
            animate();

            function init() {

                container = document.getElementById( 'container' );

                camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 20000 );
                camera.position.y = getY( worldHalfWidth, worldHalfDepth ) * 100 + 100;

                controls = new THREE.FirstPersonControls( camera );

                controls.movementSpeed = 1000;
                controls.lookSpeed = 0.125;
                controls.lookVertical = true;
                controls.constrainVertical = true;
                controls.verticalMin = 1.1;
                controls.verticalMax = 2.2;

                scene = new THREE.Scene();
                scene.fog = new THREE.FogExp2( 0xffffff, 0.00015 );

                // sides
                
                var light = new THREE.Color( 0xffffff );
                var shadow = new THREE.Color( 0x505050 );

          var light = new THREE.Color(0xffffff);
  var matrixshadow = new THREE.Matrix4Color(0x505050);

                var pxGeometrymatrix = new THREE.PlaneGeometry( 100, 100 );
                pxGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                pxGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                pxGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                pxGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                pxGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                pxGeometry.applyMatrix( matrix.makeRotationY( Math.PI / 2 ) );
                pxGeometry.applyMatrix( matrix.makeTranslationMatrix4( 50, 0, 0 ) );

                var nxGeometrypxGeometry = new THREE.PlaneGeometry( 100, 100 );
                nxGeometrypxGeometry.faces[ 0 ]faces[0].vertexColors.push( light, shadow, light );
                nxGeometrypxGeometry.faces[ 1 ]faces[1].vertexColors.push( shadow, shadow, light );
                nxGeometrypxGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ]faceVertexUvs[0][0][0].y = 0.5;
                nxGeometrypxGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ]faceVertexUvs[0][0][2].y = 0.5;
                nxGeometrypxGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ]faceVertexUvs[0][1][2].y = 0.5;
                nxGeometrypxGeometry.applyMatrix( matrix.makeRotationY( - Math.PI / 2 ) );
                nxGeometrypxGeometry.applyMatrix( matrix.makeTranslation( - 50, 0, 0 ) );

                var pyGeometrynxGeometry = new THREE.PlaneGeometry( 100, 100 );
                pyGeometrynxGeometry.faces[ 0 ]faces[0].vertexColors.push( light, lightshadow, light );
                pyGeometrynxGeometry.faces[ 1 ]faces[1].vertexColors.push( lightshadow, lightshadow, light );
                pyGeometrynxGeometry.faceVertexUvs[ 0 ][ 0 ][ 1 ]faceVertexUvs[0][0][0].y = 0.5;
                pyGeometrynxGeometry.faceVertexUvs[ 0 ][ 1 ][ 0 ]faceVertexUvs[0][0][2].y = 0.5;
                pyGeometrynxGeometry.faceVertexUvs[ 0 ][ 1 ][ 1 ]faceVertexUvs[0][1][2].y = 0.5;
                pyGeometrynxGeometry.applyMatrix( matrix.makeRotationXmakeRotationY( - Math.PI / 2 ) );
                pyGeometrynxGeometry.applyMatrix( matrix.makeTranslation( 0, -50, 0, 0) );

                var py2GeometrypyGeometry = new THREE.PlaneGeometry( 100, 100 );
                py2GeometrypyGeometry.faces[ 0 ]faces[0].vertexColors.push( light, light, light );
                py2GeometrypyGeometry.faces[ 1 ]faces[1].vertexColors.push( light, light, light );
                py2GeometrypyGeometry.faceVertexUvs[ 0 ][ 0 ][ 1 ]faceVertexUvs[0][0][1].y = 0.5;
                py2GeometrypyGeometry.faceVertexUvs[ 0 ][ 1 ][ 0 ]faceVertexUvs[0][1][0].y = 0.5;
                py2GeometrypyGeometry.faceVertexUvs[ 0 ][ 1 ][ 1 ]faceVertexUvs[0][1][1].y = 0.5;
                py2GeometrypyGeometry.applyMatrix( matrix.makeRotationX( - Math.PI / 2 ) );
                py2Geometry.applyMatrix( matrix.makeRotationY( Math.PI / 2 ) );
                py2GeometrypyGeometry.applyMatrix( matrix.makeTranslation( 0, 50, 0 ) );

                var pzGeometrypy2Geometry = new THREE.PlaneGeometry( 100, 100 );
                pzGeometrypy2Geometry.faces[ 0 ]faces[0].vertexColors.push( light, shadowlight, light );
                pzGeometrypy2Geometry.faces[ 1 ]faces[1].vertexColors.push( shadowlight, shadowlight, light );
                pzGeometrypy2Geometry.faceVertexUvs[ 0 ][ 0 ][ 0 ]faceVertexUvs[0][0][1].y = 0.5;
                pzGeometrypy2Geometry.faceVertexUvs[ 0 ][ 0 ][ 2 ]faceVertexUvs[0][1][0].y = 0.5;
                pzGeometrypy2Geometry.faceVertexUvs[ 0 ][ 1 ][ 2 ]faceVertexUvs[0][1][1].y = 0.5;
        py2Geometry.applyMatrix(matrix.makeRotationX(-Math.PI / 2));
  py2Geometry.applyMatrix(matrix.makeRotationY(Math.PI / 2));
  pzGeometrypy2Geometry.applyMatrix( matrix.makeTranslation( 0, 0, 50, 0) );

                var nzGeometrypzGeometry = new THREE.PlaneGeometry( 100, 100 );
                nzGeometrypzGeometry.faces[ 0 ]faces[0].vertexColors.push( light, shadow, light );
                nzGeometrypzGeometry.faces[ 1 ]faces[1].vertexColors.push( shadow, shadow, light );
                nzGeometrypzGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ]faceVertexUvs[0][0][0].y = 0.5;
                nzGeometrypzGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ]faceVertexUvs[0][0][2].y = 0.5;
                nzGeometrypzGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ]faceVertexUvs[0][1][2].y = 0.5;
                nzGeometry.applyMatrix( matrix.makeRotationY( Math.PI ) );
                nzGeometrypzGeometry.applyMatrix( matrix.makeTranslation( 0, 0, - 50 ) );

  var nzGeometry = new THREE.PlaneGeometry(100, 100);
  nzGeometry.faces[0].vertexColors.push(light, shadow, light);
  nzGeometry.faces[1].vertexColors.push(shadow, shadow, light);
  nzGeometry.faceVertexUvs[0][0][0].y = 0.5;
  //nzGeometry.faceVertexUvs[0][0][2].y = 0.5;
  nzGeometry.faceVertexUvs[0][1][2].y = 0.5;
  nzGeometry.applyMatrix(matrix.makeRotationY(Math.PI));
  nzGeometry.applyMatrix(matrix.makeTranslation(0, 0, -50));

                var geometry = new THREE.Geometry();
                var dummy = new THREE.Mesh();//

             var geometry = fornew THREE.Geometry();
  var zdummy = 0; z < worldDepth; z ++new THREE.Mesh() {;

                    for ( var xz = 0; xz < worldWidth; x ++worldDepth; z++) {

                       for (var hx = getY(0; x, z< worldWidth; x++); {

                     var h = matrix.makeTranslationgetY(
                            x * 100 - worldHalfWidth * 100,
                            h * 100,
                            z * 100 - worldHalfDepth * 100
                        );

                        var px = getYmatrix.makeTranslation( x + 1, z );
                        var nx =x getY(* x100 - 1,worldHalfWidth z* );100,
                        var pz =h getY(* x100, z + 1 );
                    z * 100 - varworldHalfDepth nz* =100
 getY( x, z - 1 );

                        var pxpzpx = getY( x + 1, z + 1 );
                        var nxpznx = getY( x - 1, z + 1 );
                        var pxnzpz = getY( x + 1, z -+ 1 );
                        var nxnznz = getY( x - 1, z - 1 );

                        var apxpz = nx > h || nz > h || nxnz >getY(x h+ ?1, 0z :+ 1;1);
                        var bnxpz = nx > h || pz > h || nxpz >getY(x h- ?1, 0z :+ 1;1);
                        var cpxnz = px > h || pz > h || pxpz >getY(x h+ ?1, 0z :- 1;1);
                        var dnxnz = px > h || nz > h || pxnz >getY(x h- ?1, 0z :- 1;1);

      var a = nx > h || nz > h || nxnz > h ? 0 : 1;
 if ( a +  var b = nx > h || pz > h || nxpz > h ? 0 : 1;
      var c = px > bh +|| pz > h || pxpz > h ? 0 : 1;
      var d )= {px > h || nz > h || pxnz > h ? 0 : 1;

                            var colors = py2Geometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = b === 0 ? shadow : light;
                            colors[ 1if ](a =+ c === 0 ? shadow : light;
                            colors[ 2 ] = a === 0> ?b shadow+ :d) light;{

                            var colors = py2Geometry.faces[ 1 ]faces[0].vertexColors;
                            colors[ 0 ]colors[0] = cb === 0 ? shadow : light;
                            colors[ 1 ]colors[1] = dc === 0 ? shadow : light;
                            colors[ 2 ]colors[2] = a === 0 ? shadow : light;
                            
                            geometry.merge( py2Geometry, matrix );

        var colors = py2Geometry.faces[1].vertexColors;
        colors[0] = c === 0 }? elseshadow {: light;
        colors[1] = d === 0 ? shadow : light;
        colors[2] = a === 0 ? shadow : light;

                            var colors = pyGeometry.faces[ 0 ]geometry.vertexColors;
                            colors[ 0 ] = a === 0 ? shadow : light;
                            colors[ 1 ] = b === 0 ? shadow : light;
                            colors[ 2 ] = d === 0 ? shadow :merge(py2Geometry, light;matrix);

                            var colors = pyGeometry.faces[ 1 ].vertexColors;
                            colors[ 0 ] = b === 0 ? shadow : light;
                            colors[ 1 ] = c === 0 ? shadow : light;
                            colors[ 2 ] = d === 0 ? shadow : light;
                            
                            geometry.merge( pyGeometry,} matrixelse );{

        var colors = pyGeometry.faces[0].vertexColors;
        colors[0] = a === 0 }? shadow : light;
        colors[1] = b === 0 ? shadow : light;
        colors[2] = d === 0 ? shadow : light;

        var colors = pyGeometry.faces[1].vertexColors;
        colors[0] = b === 0 if? (shadow (: pxlight;
 != h && px !   colors[1] = hc +=== 10 )? ||shadow x: ==light;
        colors[2] = d === 0 )? {shadow : light;

                            var colors = pxGeometry.faces[ 0 ]geometry.vertexColors;
                            colors[ 0 ] = pxpz > px && x > 0 ? shadow : light;
                            colors[ 2 ] = pxnz > px && x > 0 ? shadow :merge(pyGeometry, light;matrix);

                            var colors = pxGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = pxnz > px && x > 0 ? shadow : light;}

                  if ((px != h && px != h + 1) geometry.merge(|| pxGeometry,x matrix== 0); {

        var colors = pxGeometry.faces[0].vertexColors;
        colors[0] = pxpz > px }&& x > 0 ? shadow : light;
        colors[2] = pxnz > px && x > 0 ? shadow : light;

                    var colors = pxGeometry.faces[1].vertexColors;
 if ( ( nx != h && nxcolors[2] != h +pxnz 1> )px ||&& x ==> worldWidth0 -? 1shadow ): {light;

                            var colors = nxGeometry.faces[ 0 ]geometry.vertexColors;
                            colors[ 0 ] = nxnz > nx && x < worldWidth - 1 ? shadow : light;
                            colors[ 2 ] = nxpz > nx && x < worldWidth - 1 ? shadow :merge(pxGeometry, light;matrix);

                            var colors = nxGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = nxpz > nx && x < worldWidth - 1 ? shadow : light;}

                if ((nx != h && nx != h + 1) || x geometry.merge(== nxGeometry,worldWidth matrix- 1); {

        var colors = nxGeometry.faces[0].vertexColors;
        colors[0] = nxnz > nx && }x < worldWidth - 1 ? shadow : light;
        colors[2] = nxpz > nx && x < worldWidth - 1 ? shadow : light;

              var colors = nxGeometry.faces[1].vertexColors;
       if (colors[2] (= pznxpz !=> hnx && pzx !=< hworldWidth +- 1 ) || z == worldDepth -? 1shadow ): {light;

                            var colors = pzGeometry.faces[ 0 ]geometry.vertexColors;
                            colors[ 0 ] = nxpz > pz && z < worldDepth - 1 ? shadow : light;
                            colors[ 2 ] = pxpz > pz && z < worldDepth - 1 ? shadow :merge(nxGeometry, light;matrix);

                            var colors = pzGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = pxpz > pz && z < worldDepth - 1 ? shadow : light;}

                if ((pz != h && pz != h + 1) || z geometry.merge(== pzGeometry,worldDepth matrix- 1); {

        var colors = pzGeometry.faces[0].vertexColors;
        colors[0] = nxpz > pz && }z < worldDepth - 1 ? shadow : light;
        colors[2] = pxpz > pz && z < worldDepth - 1 ? shadow : light;

              var colors = pzGeometry.faces[1].vertexColors;
       if (colors[2] (= nzpxpz !=> hpz && nzz !=< hworldDepth +- 1 ) || z ==? 0shadow ): {light;

                            var colors = nzGeometry.faces[ 0 ]geometry.vertexColors;
                            colors[ 0 ] = pxnz > nz && z > 0 ? shadow : light;
                            colors[ 2 ] = nxnz > nz && z > 0 ? shadow :merge(pzGeometry, light;matrix);

                            var colors = nzGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = nxnz > nz && z > 0 ? shadow : light;}

                  if ((nz != h && nz != h + 1) geometry.merge(|| nzGeometry,z matrix== 0); {

        var colors = nzGeometry.faces[0].vertexColors;
        colors[0] = pxnz > nz }&& z > 0 ? shadow : light;
        colors[2] = nxnz > nz && z > 0 ? shadow : light;

        var colors = nzGeometry.faces[1].vertexColors;
        colors[2] }= nxnz > nz && z > 0 ? shadow : light;

               geometry.merge(nzGeometry, }matrix);

                var texture = THREE.ImageUtils.loadTexture( 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAgCAMAAAAsVwj+AAABv1BMVEUcQwAiTgElVAEqVgA5YgJJbQNQcghffgsnVAE0YQFxWjNxWTN2XzptWDVwVzJxVzMiUQBBbQN1XjloUC2AZUGAaEGNcUlMORcgUABRbgZVRQhWQR1YRiJ1XjVfRyVfTCd8YkF8Yz5/ZD8+KweAZUKAZURjTCeAaESMcUlnTy2OdEqQdk1SOhlTPxxTQSJTRAhUPBxURQhUdwk3Lgc5MxVWRQdWRidXQyJXSghXTykwLRBZRSFbTA5cRiddRyddTC5eRyheSyZeSygyLRI+Lgc+OhZgTChhTCdiUwxALgdjTidmTycpIwdnUC1nUDBCPCZoUS1oVC5pUy5pVxZqUy1rUixrUy1rVTBtVDJtVjJDMBVvVzNvWTNFNwdwWDJwWDhwWzhFPQdGQCdHNRJzWzNzWzt0XDpHNRVHPgd1XjtJNA92Yjx5YTl6Yzx7Yzs1YQFLRRt8ZEE2Lgd/ZURMOhdMOhpNNxZNRQdNRyiBa0ODZUGDaUGFbD+GbUSHbUeIbEOIbESIbEWIbUSIbUWIbkWJbkWJcUmKbUiLcUdPOheMckiNcUdQRwiNckqNdEmNdEqNdE02MSWPdUk3KAeVeFD3vhDZAAABm0lEQVR4XkWQU69mQRBFy330Gdc2xrZt27Zt2/ODp07uw2R3qpOVnZVKQTAyf6TGyKYIqEymLOIDhRRQzJQssAnmAQpBhM28Z+JFEENDUnURmRiDiUdJmP3LHYrEjHmERCiA641MjYRMCAnYuXvYKbOKgk7tQRpUObCBoGLAvC7IzoE1mKpwblJSAnJHQNexICkbsCtNBUUUXcVAZsZKFNTUnQRIZChqYt4XFm/8v0dUmbpHa4Vy040Io1YHXIkdzY4qEa5bHDloa4OoHMdlhPjrnyiCmzEuQvy142K8EOuH5pZhaRT3Pzi9cd6M8vWHj+qbbkNp66lve2aNvjuwpmPOWG3/MXi6tr3x+Mnv5vT2s0l1e0sJ1p9Jr355WV12olkfnry3oAXSnstZdmFaczwdLnkyaGRDd+f/SAqNFxODxeJQLwx+Hh/dVe361N3V7L/fMbMGEx+//327c0PPlTTtO1rrWwVj7589L3QfWZm9er383J2fCayuLikkh1d0bv4wsu1N78kEkuN7dw9s6bw2UBw5eGnfrfP/AEXsNS9OBYAmAAAAAElFTkSuQmCC' );
                texture.magFilter = THREE.NearestFilter;
                texture.minFilter = THREE.LinearMipMapLinearFilter;}

                var mesh = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { map: texture, ambient: 0xbbbbbb, vertexColors: THREE.VertexColors } ) );
                scene.add( mesh );

                var ambientLight = new THREE.AmbientLight( 0xcccccc );
                scene.add( ambientLight );}

                var directionalLighttexture = new THREE.DirectionalLightImageUtils.loadTexture( 0xffffff'data:image/png;base64, 2 iVBORw0KGgoAAAANSUhEUgAAABAAAAAgCAMAAAAsVwj+AAABv1BMVEUcQwAiTgElVAEqVgA5YgJJbQNQcghffgsnVAE0YQFxWjNxWTN2XzptWDVwVzJxVzMiUQBBbQN1XjloUC2AZUGAaEGNcUlMORcgUABRbgZVRQhWQR1YRiJ1XjVfRyVfTCd8YkF8Yz5/ZD8+KweAZUKAZURjTCeAaESMcUlnTy2OdEqQdk1SOhlTPxxTQSJTRAhUPBxURQhUdwk3Lgc5MxVWRQdWRidXQyJXSghXTykwLRBZRSFbTA5cRiddRyddTC5eRyheSyZeSygyLRI+Lgc+OhZgTChhTCdiUwxALgdjTidmTycpIwdnUC1nUDBCPCZoUS1oVC5pUy5pVxZqUy1rUixrUy1rVTBtVDJtVjJDMBVvVzNvWTNFNwdwWDJwWDhwWzhFPQdGQCdHNRJzWzNzWzt0XDpHNRVHPgd1XjtJNA92Yjx5YTl6Yzx7Yzs1YQFLRRt8ZEE2Lgd/ZURMOhdMOhpNNxZNRQdNRyiBa0ODZUGDaUGFbD+GbUSHbUeIbEOIbESIbEWIbUSIbUWIbkWJbkWJcUmKbUiLcUdPOheMckiNcUdQRwiNckqNdEmNdEqNdE02MSWPdUk3KAeVeFD3vhDZAAABm0lEQVR4XkWQU69mQRBFy330Gdc2xrZt27Zt2/ODp07uw2R3qpOVnZVKQTAyf6TGyKYIqEymLOIDhRRQzJQssAnmAQpBhM28Z+JFEENDUnURmRiDiUdJmP3LHYrEjHmERCiA641MjYRMCAnYuXvYKbOKgk7tQRpUObCBoGLAvC7IzoE1mKpwblJSAnJHQNexICkbsCtNBUUUXcVAZsZKFNTUnQRIZChqYt4XFm/8v0dUmbpHa4Vy040Io1YHXIkdzY4qEa5bHDloa4OoHMdlhPjrnyiCmzEuQvy142K8EOuH5pZhaRT3Pzi9cd6M8vWHj+qbbkNp66lve2aNvjuwpmPOWG3/MXi6tr3x+Mnv5vT2s0l1e0sJ1p9Jr355WV12olkfnry3oAXSnstZdmFaczwdLnkyaGRDd+f/SAqNFxODxeJQLwx+Hh/dVe361N3V7L/fMbMGEx+//327c0PPlTTtO1rrWwVj7589L3QfWZm9er383J2fCayuLikkh1d0bv4wsu1N78kEkuN7dw9s6bw2UBw5eGnfrfP/AEXsNS9OBYAmAAAAAElFTkSuQmCC');
                directionalLight.positiontexture.set( 1, 1,magFilter 0.5= )THREE.normalize();NearestFilter;
                scenetexture.add(minFilter directionalLight= );THREE.LinearMipMapLinearFilter;

             var mesh = renderernew =THREE.Mesh(geometry, new THREE.WebGLRendererMeshLambertMaterial();{
     map: texture,
    ambient: 0xbbbbbb,
    vertexColors: rendererTHREE.setClearColor(VertexColors
 0xffffff }));
                rendererscene.setSizeadd( window.innerWidth, window.innerHeight mesh);

            var ambientLight = new containerTHREE.innerHTMLAmbientLight(0xcccccc);
 = "";scene.add(ambientLight);

       var directionalLight = new THREE.DirectionalLight(0xffffff, 2);
  directionalLight.position.set(1, 1, container0.appendChild5).normalize();
 renderer.domElement scene.add(directionalLight);

                statsrenderer = new StatsTHREE.WebGLRenderer();
                stats.domElement.style.position = 'absolute';
                stats.domElement.stylerenderer.top = '0px';setClearColor(0xffffff);
                containerrenderer.appendChildsetSize( statswindow.domElementinnerWidth, window.innerHeight);

              container.innerHTML = //"";

                windowcontainer.addEventListenerappendChild( 'resize', onWindowResize, false renderer.domElement);

  stats = new Stats();
  stats.domElement.style.position = 'absolute';
  stats.domElement.style.top }= '0px';
  container.appendChild(stats.domElement);

            function onWindowResize() {//

                camera.aspect = window.innerWidth / window.innerHeight;
              addEventListener('resize', onWindowResize, camera.updateProjectionMatrix(false);

                renderer.setSize( window.innerWidth, window.innerHeight );}

               function controls.handleResizeonWindowResize(); {

      camera.aspect = window.innerWidth / window.innerHeight;
  }camera.updateProjectionMatrix();

            function loadTexturerenderer.setSize( pathwindow.innerWidth, callback window.innerHeight) {;

                var image = new Imagecontrols.handleResize();

                image.onload = function () { callback(); };
                image.src = path;

              function loadTexture(path, returncallback) image;{

        var image = new }Image();

    image.onload = function() {
    callback();
 function generateHeight(};
 width, heightimage.src )= {path;

                var data = [], perlin = new ImprovedNoise(),
                size = width * height, quality = 2, z = Math.random() *return 100;image;

                for ( var j = 0; j < 4; j ++ ) {}

                    if ( j == 0 ) forfunction generateHeight( var i = 0; i < size; i ++width, height) data[ i ] = 0;{

  var data = [],
    perlin = new ImprovedNoise(),
    size = width * forheight,
 ( var i quality = 0;2,
 i < size; iz ++= Math.random() {* 100;

                       for (var x = i % width, yj = ( i / width ) | 0;
                        data[ i ] += perlin.noise( x / quality, y /j quality,< z4; j++) * quality;{

    if (j == 0)
      for (var i = 0; i < size; i++) data[i] = }0;

             for (var i = 0; i < qualitysize; *=i++) 4{

      var x = i % width,
        y = }(i / width) | 0;
      data[i] += perlin.noise(x / quality, y / quality, z) * quality;

                return data;}

          quality *= }4

            function getY( x, z ) {}

                return ( data[ x + z * worldWidth ] * 0.2 ) | 0;data;

            }

         function getY(x, z) //{

      return (data[x + z * worldWidth] function* animate(0.2) {| 0;

                requestAnimationFrame( animate );}

                render();
                stats.update();//

          function animate() }{

            function renderrequestAnimationFrame(animate) {;

                controls.update( clock.getDeltarender() );
                rendererstats.renderupdate( scene, camera );

     }

function render() {

  controls.update(clock.getDelta());
  renderer.render(scene, camera);

}
            body {
                color: #61443e;
                font-family: Monospace;
                font-size: 13px;
                text-align: center;
 
                /* background-color: #bfd1e5; */
                background-color: #ffffff;
                margin: 0px;
                overflow: hidden;
            }

            a {
  color: #a06851;  
}

            #info {
                position: absolute;
                top: 0px;
  width: 100%;
                padding: 5px;
            }

            #oldie {
                background: rgb(100, 0, 0) !important;
                color: #fff !important;
                margin-top: 10em !important;
            }
             
#oldie a {
  color:#fff #fff
}
        <div id="container"><br /><br /><br /><br /><br />Generating world...</div>
        <div id="info">
            <a href="http://threejs.org" target="_blank">three.js</a> - <a href="http://www.minecraft.net/" target="_blank">minecraft</a> demo [ambient occlusion]. featuring <a href="http://painterlypack.net/" target="_blank">painterly pack</a><br />(left click:
  forward, right click: backward)
        </div>

        <script src="https://threejs.org/build/three.min.js"></script>

        <script src="https://threejs.org/examples/js/controls/FirstPersonControls.js"></script>

        <script src="https://threejs.org/examples/js/ImprovedNoise.js"></script>

        <script src="https://threejs.org/examples/js/Detector.js"></script>
        <script src="https://threejs.org/examples/js/libs/stats.min.js"></script>

        <script>
 
        </script>
            if ( ! Detector.webgl ) {

                Detector.addGetWebGLMessage();
                document.getElementById( 'container' ).innerHTML = "";

            }

            var fogExp2 = true;

            var container, stats;

            var camera, controls, scene, renderer;

            var mesh, mat;

            var worldWidth = 200, worldDepth = 200,
            worldHalfWidth = worldWidth / 2, worldHalfDepth = worldDepth / 2,
            data = generateHeight( worldWidth, worldDepth );

            var clock = new THREE.Clock();

            init();
            animate();

            function init() {

                container = document.getElementById( 'container' );

                camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 20000 );
                camera.position.y = getY( worldHalfWidth, worldHalfDepth ) * 100 + 100;

                controls = new THREE.FirstPersonControls( camera );

                controls.movementSpeed = 1000;
                controls.lookSpeed = 0.125;
                controls.lookVertical = true;
                controls.constrainVertical = true;
                controls.verticalMin = 1.1;
                controls.verticalMax = 2.2;

                scene = new THREE.Scene();
                scene.fog = new THREE.FogExp2( 0xffffff, 0.00015 );

                // sides
                
                var light = new THREE.Color( 0xffffff );
                var shadow = new THREE.Color( 0x505050 );

                var matrix = new THREE.Matrix4();

                var pxGeometry = new THREE.PlaneGeometry( 100, 100 );
                pxGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                pxGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                pxGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                pxGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                pxGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                pxGeometry.applyMatrix( matrix.makeRotationY( Math.PI / 2 ) );
                pxGeometry.applyMatrix( matrix.makeTranslation( 50, 0, 0 ) );

                var nxGeometry = new THREE.PlaneGeometry( 100, 100 );
                nxGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                nxGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                nxGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                nxGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                nxGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                nxGeometry.applyMatrix( matrix.makeRotationY( - Math.PI / 2 ) );
                nxGeometry.applyMatrix( matrix.makeTranslation( - 50, 0, 0 ) );

                var pyGeometry = new THREE.PlaneGeometry( 100, 100 );
                pyGeometry.faces[ 0 ].vertexColors.push( light, light, light );
                pyGeometry.faces[ 1 ].vertexColors.push( light, light, light );
                pyGeometry.faceVertexUvs[ 0 ][ 0 ][ 1 ].y = 0.5;
                pyGeometry.faceVertexUvs[ 0 ][ 1 ][ 0 ].y = 0.5;
                pyGeometry.faceVertexUvs[ 0 ][ 1 ][ 1 ].y = 0.5;
                pyGeometry.applyMatrix( matrix.makeRotationX( - Math.PI / 2 ) );
                pyGeometry.applyMatrix( matrix.makeTranslation( 0, 50, 0 ) );

                var py2Geometry = new THREE.PlaneGeometry( 100, 100 );
                py2Geometry.faces[ 0 ].vertexColors.push( light, light, light );
                py2Geometry.faces[ 1 ].vertexColors.push( light, light, light );
                py2Geometry.faceVertexUvs[ 0 ][ 0 ][ 1 ].y = 0.5;
                py2Geometry.faceVertexUvs[ 0 ][ 1 ][ 0 ].y = 0.5;
                py2Geometry.faceVertexUvs[ 0 ][ 1 ][ 1 ].y = 0.5;
                py2Geometry.applyMatrix( matrix.makeRotationX( - Math.PI / 2 ) );
                py2Geometry.applyMatrix( matrix.makeRotationY( Math.PI / 2 ) );
                py2Geometry.applyMatrix( matrix.makeTranslation( 0, 50, 0 ) );

                var pzGeometry = new THREE.PlaneGeometry( 100, 100 );
                pzGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                pzGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                pzGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                pzGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                pzGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                pzGeometry.applyMatrix( matrix.makeTranslation( 0, 0, 50 ) );

                var nzGeometry = new THREE.PlaneGeometry( 100, 100 );
                nzGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                nzGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                nzGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                nzGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                nzGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                nzGeometry.applyMatrix( matrix.makeRotationY( Math.PI ) );
                nzGeometry.applyMatrix( matrix.makeTranslation( 0, 0, - 50 ) );

                //

                var geometry = new THREE.Geometry();
                var dummy = new THREE.Mesh();

                for ( var z = 0; z < worldDepth; z ++ ) {

                    for ( var x = 0; x < worldWidth; x ++ ) {

                        var h = getY( x, z );

                        matrix.makeTranslation(
                            x * 100 - worldHalfWidth * 100,
                            h * 100,
                            z * 100 - worldHalfDepth * 100
                        );

                        var px = getY( x + 1, z );
                        var nx = getY( x - 1, z );
                        var pz = getY( x, z + 1 );
                        var nz = getY( x, z - 1 );

                        var pxpz = getY( x + 1, z + 1 );
                        var nxpz = getY( x - 1, z + 1 );
                        var pxnz = getY( x + 1, z - 1 );
                        var nxnz = getY( x - 1, z - 1 );

                        var a = nx > h || nz > h || nxnz > h ? 0 : 1;
                        var b = nx > h || pz > h || nxpz > h ? 0 : 1;
                        var c = px > h || pz > h || pxpz > h ? 0 : 1;
                        var d = px > h || nz > h || pxnz > h ? 0 : 1;

                        if ( a + c > b + d ) {

                            var colors = py2Geometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = b === 0 ? shadow : light;
                            colors[ 1 ] = c === 0 ? shadow : light;
                            colors[ 2 ] = a === 0 ? shadow : light;

                            var colors = py2Geometry.faces[ 1 ].vertexColors;
                            colors[ 0 ] = c === 0 ? shadow : light;
                            colors[ 1 ] = d === 0 ? shadow : light;
                            colors[ 2 ] = a === 0 ? shadow : light;
                            
                            geometry.merge( py2Geometry, matrix );

                        } else {

                            var colors = pyGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = a === 0 ? shadow : light;
                            colors[ 1 ] = b === 0 ? shadow : light;
                            colors[ 2 ] = d === 0 ? shadow : light;

                            var colors = pyGeometry.faces[ 1 ].vertexColors;
                            colors[ 0 ] = b === 0 ? shadow : light;
                            colors[ 1 ] = c === 0 ? shadow : light;
                            colors[ 2 ] = d === 0 ? shadow : light;
                            
                            geometry.merge( pyGeometry, matrix );

                        }

                        if ( ( px != h && px != h + 1 ) || x == 0 ) {

                            var colors = pxGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = pxpz > px && x > 0 ? shadow : light;
                            colors[ 2 ] = pxnz > px && x > 0 ? shadow : light;

                            var colors = pxGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = pxnz > px && x > 0 ? shadow : light;

                            geometry.merge( pxGeometry, matrix );

                        }

                        if ( ( nx != h && nx != h + 1 ) || x == worldWidth - 1 ) {

                            var colors = nxGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = nxnz > nx && x < worldWidth - 1 ? shadow : light;
                            colors[ 2 ] = nxpz > nx && x < worldWidth - 1 ? shadow : light;

                            var colors = nxGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = nxpz > nx && x < worldWidth - 1 ? shadow : light;

                            geometry.merge( nxGeometry, matrix );

                        }

                        if ( ( pz != h && pz != h + 1 ) || z == worldDepth - 1 ) {

                            var colors = pzGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = nxpz > pz && z < worldDepth - 1 ? shadow : light;
                            colors[ 2 ] = pxpz > pz && z < worldDepth - 1 ? shadow : light;

                            var colors = pzGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = pxpz > pz && z < worldDepth - 1 ? shadow : light;

                            geometry.merge( pzGeometry, matrix );

                        }

                        if ( ( nz != h && nz != h + 1 ) || z == 0 ) {

                            var colors = nzGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = pxnz > nz && z > 0 ? shadow : light;
                            colors[ 2 ] = nxnz > nz && z > 0 ? shadow : light;

                            var colors = nzGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = nxnz > nz && z > 0 ? shadow : light;

                            geometry.merge( nzGeometry, matrix );

                        }

                    }

                }

                var texture = THREE.ImageUtils.loadTexture( 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAgCAMAAAAsVwj+AAABv1BMVEUcQwAiTgElVAEqVgA5YgJJbQNQcghffgsnVAE0YQFxWjNxWTN2XzptWDVwVzJxVzMiUQBBbQN1XjloUC2AZUGAaEGNcUlMORcgUABRbgZVRQhWQR1YRiJ1XjVfRyVfTCd8YkF8Yz5/ZD8+KweAZUKAZURjTCeAaESMcUlnTy2OdEqQdk1SOhlTPxxTQSJTRAhUPBxURQhUdwk3Lgc5MxVWRQdWRidXQyJXSghXTykwLRBZRSFbTA5cRiddRyddTC5eRyheSyZeSygyLRI+Lgc+OhZgTChhTCdiUwxALgdjTidmTycpIwdnUC1nUDBCPCZoUS1oVC5pUy5pVxZqUy1rUixrUy1rVTBtVDJtVjJDMBVvVzNvWTNFNwdwWDJwWDhwWzhFPQdGQCdHNRJzWzNzWzt0XDpHNRVHPgd1XjtJNA92Yjx5YTl6Yzx7Yzs1YQFLRRt8ZEE2Lgd/ZURMOhdMOhpNNxZNRQdNRyiBa0ODZUGDaUGFbD+GbUSHbUeIbEOIbESIbEWIbUSIbUWIbkWJbkWJcUmKbUiLcUdPOheMckiNcUdQRwiNckqNdEmNdEqNdE02MSWPdUk3KAeVeFD3vhDZAAABm0lEQVR4XkWQU69mQRBFy330Gdc2xrZt27Zt2/ODp07uw2R3qpOVnZVKQTAyf6TGyKYIqEymLOIDhRRQzJQssAnmAQpBhM28Z+JFEENDUnURmRiDiUdJmP3LHYrEjHmERCiA641MjYRMCAnYuXvYKbOKgk7tQRpUObCBoGLAvC7IzoE1mKpwblJSAnJHQNexICkbsCtNBUUUXcVAZsZKFNTUnQRIZChqYt4XFm/8v0dUmbpHa4Vy040Io1YHXIkdzY4qEa5bHDloa4OoHMdlhPjrnyiCmzEuQvy142K8EOuH5pZhaRT3Pzi9cd6M8vWHj+qbbkNp66lve2aNvjuwpmPOWG3/MXi6tr3x+Mnv5vT2s0l1e0sJ1p9Jr355WV12olkfnry3oAXSnstZdmFaczwdLnkyaGRDd+f/SAqNFxODxeJQLwx+Hh/dVe361N3V7L/fMbMGEx+//327c0PPlTTtO1rrWwVj7589L3QfWZm9er383J2fCayuLikkh1d0bv4wsu1N78kEkuN7dw9s6bw2UBw5eGnfrfP/AEXsNS9OBYAmAAAAAElFTkSuQmCC' );
                texture.magFilter = THREE.NearestFilter;
                texture.minFilter = THREE.LinearMipMapLinearFilter;

                var mesh = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { map: texture, ambient: 0xbbbbbb, vertexColors: THREE.VertexColors } ) );
                scene.add( mesh );

                var ambientLight = new THREE.AmbientLight( 0xcccccc );
                scene.add( ambientLight );

                var directionalLight = new THREE.DirectionalLight( 0xffffff, 2 );
                directionalLight.position.set( 1, 1, 0.5 ).normalize();
                scene.add( directionalLight );

                renderer = new THREE.WebGLRenderer();
                renderer.setClearColor( 0xffffff );
                renderer.setSize( window.innerWidth, window.innerHeight );

                container.innerHTML = "";

                container.appendChild( renderer.domElement );

                stats = new Stats();
                stats.domElement.style.position = 'absolute';
                stats.domElement.style.top = '0px';
                container.appendChild( stats.domElement );

                //

                window.addEventListener( 'resize', onWindowResize, false );

            }

            function onWindowResize() {

                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();

                renderer.setSize( window.innerWidth, window.innerHeight );

                controls.handleResize();

            }

            function loadTexture( path, callback ) {

                var image = new Image();

                image.onload = function () { callback(); };
                image.src = path;

                return image;

            }

            function generateHeight( width, height ) {

                var data = [], perlin = new ImprovedNoise(),
                size = width * height, quality = 2, z = Math.random() * 100;

                for ( var j = 0; j < 4; j ++ ) {

                    if ( j == 0 ) for ( var i = 0; i < size; i ++ ) data[ i ] = 0;

                    for ( var i = 0; i < size; i ++ ) {

                        var x = i % width, y = ( i / width ) | 0;
                        data[ i ] += perlin.noise( x / quality, y / quality, z ) * quality;

                    }

                    quality *= 4

                }

                return data;

            }

            function getY( x, z ) {

                return ( data[ x + z * worldWidth ] * 0.2 ) | 0;

            }

            //

            function animate() {

                requestAnimationFrame( animate );

                render();
                stats.update();

            }

            function render() {

                controls.update( clock.getDelta() );
                renderer.render( scene, camera );

            }
            body {
                color: #61443e;
                font-family:Monospace;
                font-size:13px;
                text-align:center;
 
                /* background-color: #bfd1e5; */
                background-color: #ffffff;
                margin: 0px;
                overflow: hidden;
            }

            a { color: #a06851; }

            #info {
                position: absolute;
                top: 0px; width: 100%;
                padding: 5px;
            }

            #oldie {
                background:rgb(100,0,0) !important;
                color:#fff !important;
                margin-top:10em !important;
            }
            #oldie a { color:#fff }
        <div id="container"><br /><br /><br /><br /><br />Generating world...</div>
        <div id="info">
            <a href="http://threejs.org" target="_blank">three.js</a> - <a href="http://www.minecraft.net/" target="_blank">minecraft</a> demo [ambient occlusion]. featuring <a href="http://painterlypack.net/" target="_blank">painterly pack</a><br />(left click: forward, right click: backward)
        </div>

        <script src="https://threejs.org/build/three.min.js"></script>

        <script src="https://threejs.org/examples/js/controls/FirstPersonControls.js"></script>

        <script src="https://threejs.org/examples/js/ImprovedNoise.js"></script>

        <script src="https://threejs.org/examples/js/Detector.js"></script>
        <script src="https://threejs.org/examples/js/libs/stats.min.js"></script>

        <script>
 
        </script>
if (!Detector.webgl) {

  Detector.addGetWebGLMessage();
  document.getElementById('container').innerHTML = "";

}

var fogExp2 = true;

var container, stats;

var camera, controls, scene, renderer;

var mesh, mat;

var worldWidth = 200,
  worldDepth = 200,
  worldHalfWidth = worldWidth / 2,
  worldHalfDepth = worldDepth / 2,
  data = generateHeight(worldWidth, worldDepth);

var clock = new THREE.Clock();

init();
animate();

function init() {

  container = document.getElementById('container');

  camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 20000);
  camera.position.y = getY(worldHalfWidth, worldHalfDepth) * 100 + 100;

  controls = new THREE.FirstPersonControls(camera);

  controls.movementSpeed = 1000;
  controls.lookSpeed = 0.125;
  controls.lookVertical = true;
  controls.constrainVertical = true;
  controls.verticalMin = 1.1;
  controls.verticalMax = 2.2;

  scene = new THREE.Scene();
  scene.fog = new THREE.FogExp2(0xffffff, 0.00015);

  // sides

  var light = new THREE.Color(0xffffff);
  var shadow = new THREE.Color(0x505050);

  var matrix = new THREE.Matrix4();

  var pxGeometry = new THREE.PlaneGeometry(100, 100);
  pxGeometry.faces[0].vertexColors.push(light, shadow, light);
  pxGeometry.faces[1].vertexColors.push(shadow, shadow, light);
  pxGeometry.faceVertexUvs[0][0][0].y = 0.5;
  pxGeometry.faceVertexUvs[0][0][2].y = 0.5;
  pxGeometry.faceVertexUvs[0][1][2].y = 0.5;
  pxGeometry.applyMatrix(matrix.makeRotationY(Math.PI / 2));
  pxGeometry.applyMatrix(matrix.makeTranslation(50, 0, 0));

  var nxGeometry = new THREE.PlaneGeometry(100, 100);
  nxGeometry.faces[0].vertexColors.push(light, shadow, light);
  nxGeometry.faces[1].vertexColors.push(shadow, shadow, light);
  nxGeometry.faceVertexUvs[0][0][0].y = 0.5;
  nxGeometry.faceVertexUvs[0][0][2].y = 0.5;
  nxGeometry.faceVertexUvs[0][1][2].y = 0.5;
  nxGeometry.applyMatrix(matrix.makeRotationY(-Math.PI / 2));
  nxGeometry.applyMatrix(matrix.makeTranslation(-50, 0, 0));

  var pyGeometry = new THREE.PlaneGeometry(100, 100);
  pyGeometry.faces[0].vertexColors.push(light, light, light);
  pyGeometry.faces[1].vertexColors.push(light, light, light);
  pyGeometry.faceVertexUvs[0][0][1].y = 0.5;
  pyGeometry.faceVertexUvs[0][1][0].y = 0.5;
  pyGeometry.faceVertexUvs[0][1][1].y = 0.5;
  pyGeometry.applyMatrix(matrix.makeRotationX(-Math.PI / 2));
  pyGeometry.applyMatrix(matrix.makeTranslation(0, 50, 0));

  var py2Geometry = new THREE.PlaneGeometry(100, 100);
  py2Geometry.faces[0].vertexColors.push(light, light, light);
  py2Geometry.faces[1].vertexColors.push(light, light, light);
  py2Geometry.faceVertexUvs[0][0][1].y = 0.5;
  py2Geometry.faceVertexUvs[0][1][0].y = 0.5;
  py2Geometry.faceVertexUvs[0][1][1].y = 0.5;
  py2Geometry.applyMatrix(matrix.makeRotationX(-Math.PI / 2));
  py2Geometry.applyMatrix(matrix.makeRotationY(Math.PI / 2));
  py2Geometry.applyMatrix(matrix.makeTranslation(0, 50, 0));

  var pzGeometry = new THREE.PlaneGeometry(100, 100);
  pzGeometry.faces[0].vertexColors.push(light, shadow, light);
  pzGeometry.faces[1].vertexColors.push(shadow, shadow, light);
  pzGeometry.faceVertexUvs[0][0][0].y = 0.5;
  pzGeometry.faceVertexUvs[0][0][2].y = 0.5;
  pzGeometry.faceVertexUvs[0][1][2].y = 0.5;
  pzGeometry.applyMatrix(matrix.makeTranslation(0, 0, 50));

  var nzGeometry = new THREE.PlaneGeometry(100, 100);
  nzGeometry.faces[0].vertexColors.push(light, shadow, light);
  nzGeometry.faces[1].vertexColors.push(shadow, shadow, light);
  nzGeometry.faceVertexUvs[0][0][0].y = 0.5;
  nzGeometry.faceVertexUvs[0][0][2].y = 0.5;
  nzGeometry.faceVertexUvs[0][1][2].y = 0.5;
  nzGeometry.applyMatrix(matrix.makeRotationY(Math.PI));
  nzGeometry.applyMatrix(matrix.makeTranslation(0, 0, -50));

  //

  var geometry = new THREE.Geometry();
  var dummy = new THREE.Mesh();

  for (var z = 0; z < worldDepth; z++) {

    for (var x = 0; x < worldWidth; x++) {

      var h = getY(x, z);

      matrix.makeTranslation(
        x * 100 - worldHalfWidth * 100,
        h * 100,
        z * 100 - worldHalfDepth * 100
      );

      var px = getY(x + 1, z);
      var nx = getY(x - 1, z);
      var pz = getY(x, z + 1);
      var nz = getY(x, z - 1);

      var pxpz = getY(x + 1, z + 1);
      var nxpz = getY(x - 1, z + 1);
      var pxnz = getY(x + 1, z - 1);
      var nxnz = getY(x - 1, z - 1);

      var a = nx > h || nz > h || nxnz > h ? 0 : 1;
      var b = nx > h || pz > h || nxpz > h ? 0 : 1;
      var c = px > h || pz > h || pxpz > h ? 0 : 1;
      var d = px > h || nz > h || pxnz > h ? 0 : 1;

      if (a + c > b + d) {

        var colors = py2Geometry.faces[0].vertexColors;
        colors[0] = b === 0 ? shadow : light;
        colors[1] = c === 0 ? shadow : light;
        colors[2] = a === 0 ? shadow : light;

        var colors = py2Geometry.faces[1].vertexColors;
        colors[0] = c === 0 ? shadow : light;
        colors[1] = d === 0 ? shadow : light;
        colors[2] = a === 0 ? shadow : light;

        geometry.merge(py2Geometry, matrix);

      } else {

        var colors = pyGeometry.faces[0].vertexColors;
        colors[0] = a === 0 ? shadow : light;
        colors[1] = b === 0 ? shadow : light;
        colors[2] = d === 0 ? shadow : light;

        var colors = pyGeometry.faces[1].vertexColors;
        colors[0] = b === 0 ? shadow : light;
        colors[1] = c === 0 ? shadow : light;
        colors[2] = d === 0 ? shadow : light;

        geometry.merge(pyGeometry, matrix);

      }

      if ((px != h && px != h + 1) || x == 0) {

        var colors = pxGeometry.faces[0].vertexColors;
        colors[0] = pxpz > px && x > 0 ? shadow : light;
        colors[2] = pxnz > px && x > 0 ? shadow : light;

        var colors = pxGeometry.faces[1].vertexColors;
        colors[2] = pxnz > px && x > 0 ? shadow : light;

        geometry.merge(pxGeometry, matrix);

      }

      if ((nx != h && nx != h + 1) || x == worldWidth - 1) {

        var colors = nxGeometry.faces[0].vertexColors;
        colors[0] = nxnz > nx && x < worldWidth - 1 ? shadow : light;
        colors[2] = nxpz > nx && x < worldWidth - 1 ? shadow : light;

        var colors = nxGeometry.faces[1].vertexColors;
        colors[2] = nxpz > nx && x < worldWidth - 1 ? shadow : light;

        geometry.merge(nxGeometry, matrix);

      }

      if ((pz != h && pz != h + 1) || z == worldDepth - 1) {

        var colors = pzGeometry.faces[0].vertexColors;
        colors[0] = nxpz > pz && z < worldDepth - 1 ? shadow : light;
        colors[2] = pxpz > pz && z < worldDepth - 1 ? shadow : light;

        var colors = pzGeometry.faces[1].vertexColors;
        colors[2] = pxpz > pz && z < worldDepth - 1 ? shadow : light;

        geometry.merge(pzGeometry, matrix);

      }

      if ((nz != h && nz != h + 1) || z == 0) {

        var colors = nzGeometry.faces[0].vertexColors;
        colors[0] = pxnz > nz && z > 0 ? shadow : light;
        colors[2] = nxnz > nz && z > 0 ? shadow : light;

        var colors = nzGeometry.faces[1].vertexColors;
        colors[2] = nxnz > nz && z > 0 ? shadow : light;

        geometry.merge(nzGeometry, matrix);

      }

    }

  }

  var texture = THREE.ImageUtils.loadTexture('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAgCAMAAAAsVwj+AAABv1BMVEUcQwAiTgElVAEqVgA5YgJJbQNQcghffgsnVAE0YQFxWjNxWTN2XzptWDVwVzJxVzMiUQBBbQN1XjloUC2AZUGAaEGNcUlMORcgUABRbgZVRQhWQR1YRiJ1XjVfRyVfTCd8YkF8Yz5/ZD8+KweAZUKAZURjTCeAaESMcUlnTy2OdEqQdk1SOhlTPxxTQSJTRAhUPBxURQhUdwk3Lgc5MxVWRQdWRidXQyJXSghXTykwLRBZRSFbTA5cRiddRyddTC5eRyheSyZeSygyLRI+Lgc+OhZgTChhTCdiUwxALgdjTidmTycpIwdnUC1nUDBCPCZoUS1oVC5pUy5pVxZqUy1rUixrUy1rVTBtVDJtVjJDMBVvVzNvWTNFNwdwWDJwWDhwWzhFPQdGQCdHNRJzWzNzWzt0XDpHNRVHPgd1XjtJNA92Yjx5YTl6Yzx7Yzs1YQFLRRt8ZEE2Lgd/ZURMOhdMOhpNNxZNRQdNRyiBa0ODZUGDaUGFbD+GbUSHbUeIbEOIbESIbEWIbUSIbUWIbkWJbkWJcUmKbUiLcUdPOheMckiNcUdQRwiNckqNdEmNdEqNdE02MSWPdUk3KAeVeFD3vhDZAAABm0lEQVR4XkWQU69mQRBFy330Gdc2xrZt27Zt2/ODp07uw2R3qpOVnZVKQTAyf6TGyKYIqEymLOIDhRRQzJQssAnmAQpBhM28Z+JFEENDUnURmRiDiUdJmP3LHYrEjHmERCiA641MjYRMCAnYuXvYKbOKgk7tQRpUObCBoGLAvC7IzoE1mKpwblJSAnJHQNexICkbsCtNBUUUXcVAZsZKFNTUnQRIZChqYt4XFm/8v0dUmbpHa4Vy040Io1YHXIkdzY4qEa5bHDloa4OoHMdlhPjrnyiCmzEuQvy142K8EOuH5pZhaRT3Pzi9cd6M8vWHj+qbbkNp66lve2aNvjuwpmPOWG3/MXi6tr3x+Mnv5vT2s0l1e0sJ1p9Jr355WV12olkfnry3oAXSnstZdmFaczwdLnkyaGRDd+f/SAqNFxODxeJQLwx+Hh/dVe361N3V7L/fMbMGEx+//327c0PPlTTtO1rrWwVj7589L3QfWZm9er383J2fCayuLikkh1d0bv4wsu1N78kEkuN7dw9s6bw2UBw5eGnfrfP/AEXsNS9OBYAmAAAAAElFTkSuQmCC');
  texture.magFilter = THREE.NearestFilter;
  texture.minFilter = THREE.LinearMipMapLinearFilter;

  var mesh = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({
    map: texture,
    ambient: 0xbbbbbb,
    vertexColors: THREE.VertexColors
  }));
  scene.add(mesh);

  var ambientLight = new THREE.AmbientLight(0xcccccc);
  scene.add(ambientLight);

  var directionalLight = new THREE.DirectionalLight(0xffffff, 2);
  directionalLight.position.set(1, 1, 0.5).normalize();
  scene.add(directionalLight);

  renderer = new THREE.WebGLRenderer();
  renderer.setClearColor(0xffffff);
  renderer.setSize(window.innerWidth, window.innerHeight);

  container.innerHTML = "";

  container.appendChild(renderer.domElement);

  stats = new Stats();
  stats.domElement.style.position = 'absolute';
  stats.domElement.style.top = '0px';
  container.appendChild(stats.domElement);

  //

  window.addEventListener('resize', onWindowResize, false);

}

function onWindowResize() {

  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize(window.innerWidth, window.innerHeight);

  controls.handleResize();

}

function loadTexture(path, callback) {

  var image = new Image();

  image.onload = function() {
    callback();
  };
  image.src = path;

  return image;

}

function generateHeight(width, height) {

  var data = [],
    perlin = new ImprovedNoise(),
    size = width * height,
    quality = 2,
    z = Math.random() * 100;

  for (var j = 0; j < 4; j++) {

    if (j == 0)
      for (var i = 0; i < size; i++) data[i] = 0;

    for (var i = 0; i < size; i++) {

      var x = i % width,
        y = (i / width) | 0;
      data[i] += perlin.noise(x / quality, y / quality, z) * quality;

    }

    quality *= 4

  }

  return data;

}

function getY(x, z) {

  return (data[x + z * worldWidth] * 0.2) | 0;

}

//

function animate() {

  requestAnimationFrame(animate);

  render();
  stats.update();

}

function render() {

  controls.update(clock.getDelta());
  renderer.render(scene, camera);

}
body {
  color: #61443e;
  font-family: Monospace;
  font-size: 13px;
  text-align: center;
  /* background-color: #bfd1e5; */
  background-color: #ffffff;
  margin: 0px;
  overflow: hidden;
}

a {
  color: #a06851; 
}

#info {
  position: absolute;
  top: 0px;
  width: 100%;
  padding: 5px;
}

#oldie {
  background: rgb(100, 0, 0) !important;
  color: #fff !important;
  margin-top: 10em !important;
}
 
#oldie a {
  color: #fff
}
<div id="container"><br /><br /><br /><br /><br />Generating world...</div>
<div id="info">
  <a href="http://threejs.org" target="_blank">three.js</a> - <a href="http://www.minecraft.net/" target="_blank">minecraft</a> demo [ambient occlusion]. featuring <a href="http://painterlypack.net/" target="_blank">painterly pack</a><br />(left click:
  forward, right click: backward)
</div>

<script src="https://threejs.org/build/three.min.js"></script>

<script src="https://threejs.org/examples/js/controls/FirstPersonControls.js"></script>

<script src="https://threejs.org/examples/js/ImprovedNoise.js"></script>

<script src="https://threejs.org/examples/js/Detector.js"></script>
<script src="https://threejs.org/examples/js/libs/stats.min.js"></script>

<script>
</script>
HTTPSify the scripts because it's current year
Source Link
Camilo Martin
  • 1.3k
  • 7
  • 17
            if ( ! Detector.webgl ) {

                Detector.addGetWebGLMessage();
                document.getElementById( 'container' ).innerHTML = "";

            }

            var fogExp2 = true;

            var container, stats;

            var camera, controls, scene, renderer;

            var mesh, mat;

            var worldWidth = 200, worldDepth = 200,
            worldHalfWidth = worldWidth / 2, worldHalfDepth = worldDepth / 2,
            data = generateHeight( worldWidth, worldDepth );

            var clock = new THREE.Clock();

            init();
            animate();

            function init() {

                container = document.getElementById( 'container' );

                camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 20000 );
                camera.position.y = getY( worldHalfWidth, worldHalfDepth ) * 100 + 100;

                controls = new THREE.FirstPersonControls( camera );

                controls.movementSpeed = 1000;
                controls.lookSpeed = 0.125;
                controls.lookVertical = true;
                controls.constrainVertical = true;
                controls.verticalMin = 1.1;
                controls.verticalMax = 2.2;

                scene = new THREE.Scene();
                scene.fog = new THREE.FogExp2( 0xffffff, 0.00015 );

                // sides
                
                var light = new THREE.Color( 0xffffff );
                var shadow = new THREE.Color( 0x505050 );

                var matrix = new THREE.Matrix4();

                var pxGeometry = new THREE.PlaneGeometry( 100, 100 );
                pxGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                pxGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                pxGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                pxGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                pxGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                pxGeometry.applyMatrix( matrix.makeRotationY( Math.PI / 2 ) );
                pxGeometry.applyMatrix( matrix.makeTranslation( 50, 0, 0 ) );

                var nxGeometry = new THREE.PlaneGeometry( 100, 100 );
                nxGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                nxGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                nxGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                nxGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                nxGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                nxGeometry.applyMatrix( matrix.makeRotationY( - Math.PI / 2 ) );
                nxGeometry.applyMatrix( matrix.makeTranslation( - 50, 0, 0 ) );

                var pyGeometry = new THREE.PlaneGeometry( 100, 100 );
                pyGeometry.faces[ 0 ].vertexColors.push( light, light, light );
                pyGeometry.faces[ 1 ].vertexColors.push( light, light, light );
                pyGeometry.faceVertexUvs[ 0 ][ 0 ][ 1 ].y = 0.5;
                pyGeometry.faceVertexUvs[ 0 ][ 1 ][ 0 ].y = 0.5;
                pyGeometry.faceVertexUvs[ 0 ][ 1 ][ 1 ].y = 0.5;
                pyGeometry.applyMatrix( matrix.makeRotationX( - Math.PI / 2 ) );
                pyGeometry.applyMatrix( matrix.makeTranslation( 0, 50, 0 ) );

                var py2Geometry = new THREE.PlaneGeometry( 100, 100 );
                py2Geometry.faces[ 0 ].vertexColors.push( light, light, light );
                py2Geometry.faces[ 1 ].vertexColors.push( light, light, light );
                py2Geometry.faceVertexUvs[ 0 ][ 0 ][ 1 ].y = 0.5;
                py2Geometry.faceVertexUvs[ 0 ][ 1 ][ 0 ].y = 0.5;
                py2Geometry.faceVertexUvs[ 0 ][ 1 ][ 1 ].y = 0.5;
                py2Geometry.applyMatrix( matrix.makeRotationX( - Math.PI / 2 ) );
                py2Geometry.applyMatrix( matrix.makeRotationY( Math.PI / 2 ) );
                py2Geometry.applyMatrix( matrix.makeTranslation( 0, 50, 0 ) );

                var pzGeometry = new THREE.PlaneGeometry( 100, 100 );
                pzGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                pzGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                pzGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                pzGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                pzGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                pzGeometry.applyMatrix( matrix.makeTranslation( 0, 0, 50 ) );

                var nzGeometry = new THREE.PlaneGeometry( 100, 100 );
                nzGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                nzGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                nzGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                nzGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                nzGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                nzGeometry.applyMatrix( matrix.makeRotationY( Math.PI ) );
                nzGeometry.applyMatrix( matrix.makeTranslation( 0, 0, - 50 ) );

                //

                var geometry = new THREE.Geometry();
                var dummy = new THREE.Mesh();

                for ( var z = 0; z < worldDepth; z ++ ) {

                    for ( var x = 0; x < worldWidth; x ++ ) {

                        var h = getY( x, z );

                        matrix.makeTranslation(
                            x * 100 - worldHalfWidth * 100,
                            h * 100,
                            z * 100 - worldHalfDepth * 100
                        );

                        var px = getY( x + 1, z );
                        var nx = getY( x - 1, z );
                        var pz = getY( x, z + 1 );
                        var nz = getY( x, z - 1 );

                        var pxpz = getY( x + 1, z + 1 );
                        var nxpz = getY( x - 1, z + 1 );
                        var pxnz = getY( x + 1, z - 1 );
                        var nxnz = getY( x - 1, z - 1 );

                        var a = nx > h || nz > h || nxnz > h ? 0 : 1;
                        var b = nx > h || pz > h || nxpz > h ? 0 : 1;
                        var c = px > h || pz > h || pxpz > h ? 0 : 1;
                        var d = px > h || nz > h || pxnz > h ? 0 : 1;

                        if ( a + c > b + d ) {

                            var colors = py2Geometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = b === 0 ? shadow : light;
                            colors[ 1 ] = c === 0 ? shadow : light;
                            colors[ 2 ] = a === 0 ? shadow : light;

                            var colors = py2Geometry.faces[ 1 ].vertexColors;
                            colors[ 0 ] = c === 0 ? shadow : light;
                            colors[ 1 ] = d === 0 ? shadow : light;
                            colors[ 2 ] = a === 0 ? shadow : light;
                            
                            geometry.merge( py2Geometry, matrix );

                        } else {

                            var colors = pyGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = a === 0 ? shadow : light;
                            colors[ 1 ] = b === 0 ? shadow : light;
                            colors[ 2 ] = d === 0 ? shadow : light;

                            var colors = pyGeometry.faces[ 1 ].vertexColors;
                            colors[ 0 ] = b === 0 ? shadow : light;
                            colors[ 1 ] = c === 0 ? shadow : light;
                            colors[ 2 ] = d === 0 ? shadow : light;
                            
                            geometry.merge( pyGeometry, matrix );

                        }

                        if ( ( px != h && px != h + 1 ) || x == 0 ) {

                            var colors = pxGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = pxpz > px && x > 0 ? shadow : light;
                            colors[ 2 ] = pxnz > px && x > 0 ? shadow : light;

                            var colors = pxGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = pxnz > px && x > 0 ? shadow : light;

                            geometry.merge( pxGeometry, matrix );

                        }

                        if ( ( nx != h && nx != h + 1 ) || x == worldWidth - 1 ) {

                            var colors = nxGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = nxnz > nx && x < worldWidth - 1 ? shadow : light;
                            colors[ 2 ] = nxpz > nx && x < worldWidth - 1 ? shadow : light;

                            var colors = nxGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = nxpz > nx && x < worldWidth - 1 ? shadow : light;

                            geometry.merge( nxGeometry, matrix );

                        }

                        if ( ( pz != h && pz != h + 1 ) || z == worldDepth - 1 ) {

                            var colors = pzGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = nxpz > pz && z < worldDepth - 1 ? shadow : light;
                            colors[ 2 ] = pxpz > pz && z < worldDepth - 1 ? shadow : light;

                            var colors = pzGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = pxpz > pz && z < worldDepth - 1 ? shadow : light;

                            geometry.merge( pzGeometry, matrix );

                        }

                        if ( ( nz != h && nz != h + 1 ) || z == 0 ) {

                            var colors = nzGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = pxnz > nz && z > 0 ? shadow : light;
                            colors[ 2 ] = nxnz > nz && z > 0 ? shadow : light;

                            var colors = nzGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = nxnz > nz && z > 0 ? shadow : light;

                            geometry.merge( nzGeometry, matrix );

                        }

                    }

                }

                var texture = THREE.ImageUtils.loadTexture( 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAgCAMAAAAsVwj+AAABv1BMVEUcQwAiTgElVAEqVgA5YgJJbQNQcghffgsnVAE0YQFxWjNxWTN2XzptWDVwVzJxVzMiUQBBbQN1XjloUC2AZUGAaEGNcUlMORcgUABRbgZVRQhWQR1YRiJ1XjVfRyVfTCd8YkF8Yz5/ZD8+KweAZUKAZURjTCeAaESMcUlnTy2OdEqQdk1SOhlTPxxTQSJTRAhUPBxURQhUdwk3Lgc5MxVWRQdWRidXQyJXSghXTykwLRBZRSFbTA5cRiddRyddTC5eRyheSyZeSygyLRI+Lgc+OhZgTChhTCdiUwxALgdjTidmTycpIwdnUC1nUDBCPCZoUS1oVC5pUy5pVxZqUy1rUixrUy1rVTBtVDJtVjJDMBVvVzNvWTNFNwdwWDJwWDhwWzhFPQdGQCdHNRJzWzNzWzt0XDpHNRVHPgd1XjtJNA92Yjx5YTl6Yzx7Yzs1YQFLRRt8ZEE2Lgd/ZURMOhdMOhpNNxZNRQdNRyiBa0ODZUGDaUGFbD+GbUSHbUeIbEOIbESIbEWIbUSIbUWIbkWJbkWJcUmKbUiLcUdPOheMckiNcUdQRwiNckqNdEmNdEqNdE02MSWPdUk3KAeVeFD3vhDZAAABm0lEQVR4XkWQU69mQRBFy330Gdc2xrZt27Zt2/ODp07uw2R3qpOVnZVKQTAyf6TGyKYIqEymLOIDhRRQzJQssAnmAQpBhM28Z+JFEENDUnURmRiDiUdJmP3LHYrEjHmERCiA641MjYRMCAnYuXvYKbOKgk7tQRpUObCBoGLAvC7IzoE1mKpwblJSAnJHQNexICkbsCtNBUUUXcVAZsZKFNTUnQRIZChqYt4XFm/8v0dUmbpHa4Vy040Io1YHXIkdzY4qEa5bHDloa4OoHMdlhPjrnyiCmzEuQvy142K8EOuH5pZhaRT3Pzi9cd6M8vWHj+qbbkNp66lve2aNvjuwpmPOWG3/MXi6tr3x+Mnv5vT2s0l1e0sJ1p9Jr355WV12olkfnry3oAXSnstZdmFaczwdLnkyaGRDd+f/SAqNFxODxeJQLwx+Hh/dVe361N3V7L/fMbMGEx+//327c0PPlTTtO1rrWwVj7589L3QfWZm9er383J2fCayuLikkh1d0bv4wsu1N78kEkuN7dw9s6bw2UBw5eGnfrfP/AEXsNS9OBYAmAAAAAElFTkSuQmCC' );
                texture.magFilter = THREE.NearestFilter;
                texture.minFilter = THREE.LinearMipMapLinearFilter;

                var mesh = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { map: texture, ambient: 0xbbbbbb, vertexColors: THREE.VertexColors } ) );
                scene.add( mesh );

                var ambientLight = new THREE.AmbientLight( 0xcccccc );
                scene.add( ambientLight );

                var directionalLight = new THREE.DirectionalLight( 0xffffff, 2 );
                directionalLight.position.set( 1, 1, 0.5 ).normalize();
                scene.add( directionalLight );

                renderer = new THREE.WebGLRenderer();
                renderer.setClearColor( 0xffffff );
                renderer.setSize( window.innerWidth, window.innerHeight );

                container.innerHTML = "";

                container.appendChild( renderer.domElement );

                stats = new Stats();
                stats.domElement.style.position = 'absolute';
                stats.domElement.style.top = '0px';
                container.appendChild( stats.domElement );

                //

                window.addEventListener( 'resize', onWindowResize, false );

            }

            function onWindowResize() {

                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();

                renderer.setSize( window.innerWidth, window.innerHeight );

                controls.handleResize();

            }

            function loadTexture( path, callback ) {

                var image = new Image();

                image.onload = function () { callback(); };
                image.src = path;

                return image;

            }

            function generateHeight( width, height ) {

                var data = [], perlin = new ImprovedNoise(),
                size = width * height, quality = 2, z = Math.random() * 100;

                for ( var j = 0; j < 4; j ++ ) {

                    if ( j == 0 ) for ( var i = 0; i < size; i ++ ) data[ i ] = 0;

                    for ( var i = 0; i < size; i ++ ) {

                        var x = i % width, y = ( i / width ) | 0;
                        data[ i ] += perlin.noise( x / quality, y / quality, z ) * quality;

                    }

                    quality *= 4

                }

                return data;

            }

            function getY( x, z ) {

                return ( data[ x + z * worldWidth ] * 0.2 ) | 0;

            }

            //

            function animate() {

                requestAnimationFrame( animate );

                render();
                stats.update();

            }

            function render() {

                controls.update( clock.getDelta() );
                renderer.render( scene, camera );

            }
            body {
                color: #61443e;
                font-family:Monospace;
                font-size:13px;
                text-align:center;

                /* background-color: #bfd1e5; */
                background-color: #ffffff;
                margin: 0px;
                overflow: hidden;
            }

            a { color: #a06851; }

            #info {
                position: absolute;
                top: 0px; width: 100%;
                padding: 5px;
            }

            #oldie {
                background:rgb(100,0,0) !important;
                color:#fff !important;
                margin-top:10em !important;
            }
            #oldie a { color:#fff }
        <div id="container"><br /><br /><br /><br /><br />Generating world...</div>
        <div id="info">
            <a href="http://threejs.org" target="_blank">three.js</a> - <a href="http://www.minecraft.net/" target="_blank">minecraft</a> demo [ambient occlusion]. featuring <a href="http://painterlypack.net/" target="_blank">painterly pack</a><br />(left click: forward, right click: backward)
        </div>

        <script src="httpsrc="https://threejs.org/build/three.min.js"></script>

        <script src="httpsrc="https://threejs.org/examples/js/controls/FirstPersonControls.js"></script>

        <script src="httpsrc="https://threejs.org/examples/js/ImprovedNoise.js"></script>

        <script src="httpsrc="https://threejs.org/examples/js/Detector.js"></script>
        <script src="httpsrc="https://threejs.org/examples/js/libs/stats.min.js"></script>

        <script>

        </script>
            if ( ! Detector.webgl ) {

                Detector.addGetWebGLMessage();
                document.getElementById( 'container' ).innerHTML = "";

            }

            var fogExp2 = true;

            var container, stats;

            var camera, controls, scene, renderer;

            var mesh, mat;

            var worldWidth = 200, worldDepth = 200,
            worldHalfWidth = worldWidth / 2, worldHalfDepth = worldDepth / 2,
            data = generateHeight( worldWidth, worldDepth );

            var clock = new THREE.Clock();

            init();
            animate();

            function init() {

                container = document.getElementById( 'container' );

                camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 20000 );
                camera.position.y = getY( worldHalfWidth, worldHalfDepth ) * 100 + 100;

                controls = new THREE.FirstPersonControls( camera );

                controls.movementSpeed = 1000;
                controls.lookSpeed = 0.125;
                controls.lookVertical = true;
                controls.constrainVertical = true;
                controls.verticalMin = 1.1;
                controls.verticalMax = 2.2;

                scene = new THREE.Scene();
                scene.fog = new THREE.FogExp2( 0xffffff, 0.00015 );

                // sides
                
                var light = new THREE.Color( 0xffffff );
                var shadow = new THREE.Color( 0x505050 );

                var matrix = new THREE.Matrix4();

                var pxGeometry = new THREE.PlaneGeometry( 100, 100 );
                pxGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                pxGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                pxGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                pxGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                pxGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                pxGeometry.applyMatrix( matrix.makeRotationY( Math.PI / 2 ) );
                pxGeometry.applyMatrix( matrix.makeTranslation( 50, 0, 0 ) );

                var nxGeometry = new THREE.PlaneGeometry( 100, 100 );
                nxGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                nxGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                nxGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                nxGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                nxGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                nxGeometry.applyMatrix( matrix.makeRotationY( - Math.PI / 2 ) );
                nxGeometry.applyMatrix( matrix.makeTranslation( - 50, 0, 0 ) );

                var pyGeometry = new THREE.PlaneGeometry( 100, 100 );
                pyGeometry.faces[ 0 ].vertexColors.push( light, light, light );
                pyGeometry.faces[ 1 ].vertexColors.push( light, light, light );
                pyGeometry.faceVertexUvs[ 0 ][ 0 ][ 1 ].y = 0.5;
                pyGeometry.faceVertexUvs[ 0 ][ 1 ][ 0 ].y = 0.5;
                pyGeometry.faceVertexUvs[ 0 ][ 1 ][ 1 ].y = 0.5;
                pyGeometry.applyMatrix( matrix.makeRotationX( - Math.PI / 2 ) );
                pyGeometry.applyMatrix( matrix.makeTranslation( 0, 50, 0 ) );

                var py2Geometry = new THREE.PlaneGeometry( 100, 100 );
                py2Geometry.faces[ 0 ].vertexColors.push( light, light, light );
                py2Geometry.faces[ 1 ].vertexColors.push( light, light, light );
                py2Geometry.faceVertexUvs[ 0 ][ 0 ][ 1 ].y = 0.5;
                py2Geometry.faceVertexUvs[ 0 ][ 1 ][ 0 ].y = 0.5;
                py2Geometry.faceVertexUvs[ 0 ][ 1 ][ 1 ].y = 0.5;
                py2Geometry.applyMatrix( matrix.makeRotationX( - Math.PI / 2 ) );
                py2Geometry.applyMatrix( matrix.makeRotationY( Math.PI / 2 ) );
                py2Geometry.applyMatrix( matrix.makeTranslation( 0, 50, 0 ) );

                var pzGeometry = new THREE.PlaneGeometry( 100, 100 );
                pzGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                pzGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                pzGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                pzGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                pzGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                pzGeometry.applyMatrix( matrix.makeTranslation( 0, 0, 50 ) );

                var nzGeometry = new THREE.PlaneGeometry( 100, 100 );
                nzGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                nzGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                nzGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                nzGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                nzGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                nzGeometry.applyMatrix( matrix.makeRotationY( Math.PI ) );
                nzGeometry.applyMatrix( matrix.makeTranslation( 0, 0, - 50 ) );

                //

                var geometry = new THREE.Geometry();
                var dummy = new THREE.Mesh();

                for ( var z = 0; z < worldDepth; z ++ ) {

                    for ( var x = 0; x < worldWidth; x ++ ) {

                        var h = getY( x, z );

                        matrix.makeTranslation(
                            x * 100 - worldHalfWidth * 100,
                            h * 100,
                            z * 100 - worldHalfDepth * 100
                        );

                        var px = getY( x + 1, z );
                        var nx = getY( x - 1, z );
                        var pz = getY( x, z + 1 );
                        var nz = getY( x, z - 1 );

                        var pxpz = getY( x + 1, z + 1 );
                        var nxpz = getY( x - 1, z + 1 );
                        var pxnz = getY( x + 1, z - 1 );
                        var nxnz = getY( x - 1, z - 1 );

                        var a = nx > h || nz > h || nxnz > h ? 0 : 1;
                        var b = nx > h || pz > h || nxpz > h ? 0 : 1;
                        var c = px > h || pz > h || pxpz > h ? 0 : 1;
                        var d = px > h || nz > h || pxnz > h ? 0 : 1;

                        if ( a + c > b + d ) {

                            var colors = py2Geometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = b === 0 ? shadow : light;
                            colors[ 1 ] = c === 0 ? shadow : light;
                            colors[ 2 ] = a === 0 ? shadow : light;

                            var colors = py2Geometry.faces[ 1 ].vertexColors;
                            colors[ 0 ] = c === 0 ? shadow : light;
                            colors[ 1 ] = d === 0 ? shadow : light;
                            colors[ 2 ] = a === 0 ? shadow : light;
                            
                            geometry.merge( py2Geometry, matrix );

                        } else {

                            var colors = pyGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = a === 0 ? shadow : light;
                            colors[ 1 ] = b === 0 ? shadow : light;
                            colors[ 2 ] = d === 0 ? shadow : light;

                            var colors = pyGeometry.faces[ 1 ].vertexColors;
                            colors[ 0 ] = b === 0 ? shadow : light;
                            colors[ 1 ] = c === 0 ? shadow : light;
                            colors[ 2 ] = d === 0 ? shadow : light;
                            
                            geometry.merge( pyGeometry, matrix );

                        }

                        if ( ( px != h && px != h + 1 ) || x == 0 ) {

                            var colors = pxGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = pxpz > px && x > 0 ? shadow : light;
                            colors[ 2 ] = pxnz > px && x > 0 ? shadow : light;

                            var colors = pxGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = pxnz > px && x > 0 ? shadow : light;

                            geometry.merge( pxGeometry, matrix );

                        }

                        if ( ( nx != h && nx != h + 1 ) || x == worldWidth - 1 ) {

                            var colors = nxGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = nxnz > nx && x < worldWidth - 1 ? shadow : light;
                            colors[ 2 ] = nxpz > nx && x < worldWidth - 1 ? shadow : light;

                            var colors = nxGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = nxpz > nx && x < worldWidth - 1 ? shadow : light;

                            geometry.merge( nxGeometry, matrix );

                        }

                        if ( ( pz != h && pz != h + 1 ) || z == worldDepth - 1 ) {

                            var colors = pzGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = nxpz > pz && z < worldDepth - 1 ? shadow : light;
                            colors[ 2 ] = pxpz > pz && z < worldDepth - 1 ? shadow : light;

                            var colors = pzGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = pxpz > pz && z < worldDepth - 1 ? shadow : light;

                            geometry.merge( pzGeometry, matrix );

                        }

                        if ( ( nz != h && nz != h + 1 ) || z == 0 ) {

                            var colors = nzGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = pxnz > nz && z > 0 ? shadow : light;
                            colors[ 2 ] = nxnz > nz && z > 0 ? shadow : light;

                            var colors = nzGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = nxnz > nz && z > 0 ? shadow : light;

                            geometry.merge( nzGeometry, matrix );

                        }

                    }

                }

                var texture = THREE.ImageUtils.loadTexture( 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAgCAMAAAAsVwj+AAABv1BMVEUcQwAiTgElVAEqVgA5YgJJbQNQcghffgsnVAE0YQFxWjNxWTN2XzptWDVwVzJxVzMiUQBBbQN1XjloUC2AZUGAaEGNcUlMORcgUABRbgZVRQhWQR1YRiJ1XjVfRyVfTCd8YkF8Yz5/ZD8+KweAZUKAZURjTCeAaESMcUlnTy2OdEqQdk1SOhlTPxxTQSJTRAhUPBxURQhUdwk3Lgc5MxVWRQdWRidXQyJXSghXTykwLRBZRSFbTA5cRiddRyddTC5eRyheSyZeSygyLRI+Lgc+OhZgTChhTCdiUwxALgdjTidmTycpIwdnUC1nUDBCPCZoUS1oVC5pUy5pVxZqUy1rUixrUy1rVTBtVDJtVjJDMBVvVzNvWTNFNwdwWDJwWDhwWzhFPQdGQCdHNRJzWzNzWzt0XDpHNRVHPgd1XjtJNA92Yjx5YTl6Yzx7Yzs1YQFLRRt8ZEE2Lgd/ZURMOhdMOhpNNxZNRQdNRyiBa0ODZUGDaUGFbD+GbUSHbUeIbEOIbESIbEWIbUSIbUWIbkWJbkWJcUmKbUiLcUdPOheMckiNcUdQRwiNckqNdEmNdEqNdE02MSWPdUk3KAeVeFD3vhDZAAABm0lEQVR4XkWQU69mQRBFy330Gdc2xrZt27Zt2/ODp07uw2R3qpOVnZVKQTAyf6TGyKYIqEymLOIDhRRQzJQssAnmAQpBhM28Z+JFEENDUnURmRiDiUdJmP3LHYrEjHmERCiA641MjYRMCAnYuXvYKbOKgk7tQRpUObCBoGLAvC7IzoE1mKpwblJSAnJHQNexICkbsCtNBUUUXcVAZsZKFNTUnQRIZChqYt4XFm/8v0dUmbpHa4Vy040Io1YHXIkdzY4qEa5bHDloa4OoHMdlhPjrnyiCmzEuQvy142K8EOuH5pZhaRT3Pzi9cd6M8vWHj+qbbkNp66lve2aNvjuwpmPOWG3/MXi6tr3x+Mnv5vT2s0l1e0sJ1p9Jr355WV12olkfnry3oAXSnstZdmFaczwdLnkyaGRDd+f/SAqNFxODxeJQLwx+Hh/dVe361N3V7L/fMbMGEx+//327c0PPlTTtO1rrWwVj7589L3QfWZm9er383J2fCayuLikkh1d0bv4wsu1N78kEkuN7dw9s6bw2UBw5eGnfrfP/AEXsNS9OBYAmAAAAAElFTkSuQmCC' );
                texture.magFilter = THREE.NearestFilter;
                texture.minFilter = THREE.LinearMipMapLinearFilter;

                var mesh = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { map: texture, ambient: 0xbbbbbb, vertexColors: THREE.VertexColors } ) );
                scene.add( mesh );

                var ambientLight = new THREE.AmbientLight( 0xcccccc );
                scene.add( ambientLight );

                var directionalLight = new THREE.DirectionalLight( 0xffffff, 2 );
                directionalLight.position.set( 1, 1, 0.5 ).normalize();
                scene.add( directionalLight );

                renderer = new THREE.WebGLRenderer();
                renderer.setClearColor( 0xffffff );
                renderer.setSize( window.innerWidth, window.innerHeight );

                container.innerHTML = "";

                container.appendChild( renderer.domElement );

                stats = new Stats();
                stats.domElement.style.position = 'absolute';
                stats.domElement.style.top = '0px';
                container.appendChild( stats.domElement );

                //

                window.addEventListener( 'resize', onWindowResize, false );

            }

            function onWindowResize() {

                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();

                renderer.setSize( window.innerWidth, window.innerHeight );

                controls.handleResize();

            }

            function loadTexture( path, callback ) {

                var image = new Image();

                image.onload = function () { callback(); };
                image.src = path;

                return image;

            }

            function generateHeight( width, height ) {

                var data = [], perlin = new ImprovedNoise(),
                size = width * height, quality = 2, z = Math.random() * 100;

                for ( var j = 0; j < 4; j ++ ) {

                    if ( j == 0 ) for ( var i = 0; i < size; i ++ ) data[ i ] = 0;

                    for ( var i = 0; i < size; i ++ ) {

                        var x = i % width, y = ( i / width ) | 0;
                        data[ i ] += perlin.noise( x / quality, y / quality, z ) * quality;

                    }

                    quality *= 4

                }

                return data;

            }

            function getY( x, z ) {

                return ( data[ x + z * worldWidth ] * 0.2 ) | 0;

            }

            //

            function animate() {

                requestAnimationFrame( animate );

                render();
                stats.update();

            }

            function render() {

                controls.update( clock.getDelta() );
                renderer.render( scene, camera );

            }
            body {
                color: #61443e;
                font-family:Monospace;
                font-size:13px;
                text-align:center;

                /* background-color: #bfd1e5; */
                background-color: #ffffff;
                margin: 0px;
                overflow: hidden;
            }

            a { color: #a06851; }

            #info {
                position: absolute;
                top: 0px; width: 100%;
                padding: 5px;
            }

            #oldie {
                background:rgb(100,0,0) !important;
                color:#fff !important;
                margin-top:10em !important;
            }
            #oldie a { color:#fff }
        <div id="container"><br /><br /><br /><br /><br />Generating world...</div>
        <div id="info">
            <a href="http://threejs.org" target="_blank">three.js</a> - <a href="http://www.minecraft.net/" target="_blank">minecraft</a> demo [ambient occlusion]. featuring <a href="http://painterlypack.net/" target="_blank">painterly pack</a><br />(left click: forward, right click: backward)
        </div>

        <script src="http://threejs.org/build/three.min.js"></script>

        <script src="http://threejs.org/examples/js/controls/FirstPersonControls.js"></script>

        <script src="http://threejs.org/examples/js/ImprovedNoise.js"></script>

        <script src="http://threejs.org/examples/js/Detector.js"></script>
        <script src="http://threejs.org/examples/js/libs/stats.min.js"></script>

        <script>

        </script>
            if ( ! Detector.webgl ) {

                Detector.addGetWebGLMessage();
                document.getElementById( 'container' ).innerHTML = "";

            }

            var fogExp2 = true;

            var container, stats;

            var camera, controls, scene, renderer;

            var mesh, mat;

            var worldWidth = 200, worldDepth = 200,
            worldHalfWidth = worldWidth / 2, worldHalfDepth = worldDepth / 2,
            data = generateHeight( worldWidth, worldDepth );

            var clock = new THREE.Clock();

            init();
            animate();

            function init() {

                container = document.getElementById( 'container' );

                camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 20000 );
                camera.position.y = getY( worldHalfWidth, worldHalfDepth ) * 100 + 100;

                controls = new THREE.FirstPersonControls( camera );

                controls.movementSpeed = 1000;
                controls.lookSpeed = 0.125;
                controls.lookVertical = true;
                controls.constrainVertical = true;
                controls.verticalMin = 1.1;
                controls.verticalMax = 2.2;

                scene = new THREE.Scene();
                scene.fog = new THREE.FogExp2( 0xffffff, 0.00015 );

                // sides
                
                var light = new THREE.Color( 0xffffff );
                var shadow = new THREE.Color( 0x505050 );

                var matrix = new THREE.Matrix4();

                var pxGeometry = new THREE.PlaneGeometry( 100, 100 );
                pxGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                pxGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                pxGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                pxGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                pxGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                pxGeometry.applyMatrix( matrix.makeRotationY( Math.PI / 2 ) );
                pxGeometry.applyMatrix( matrix.makeTranslation( 50, 0, 0 ) );

                var nxGeometry = new THREE.PlaneGeometry( 100, 100 );
                nxGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                nxGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                nxGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                nxGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                nxGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                nxGeometry.applyMatrix( matrix.makeRotationY( - Math.PI / 2 ) );
                nxGeometry.applyMatrix( matrix.makeTranslation( - 50, 0, 0 ) );

                var pyGeometry = new THREE.PlaneGeometry( 100, 100 );
                pyGeometry.faces[ 0 ].vertexColors.push( light, light, light );
                pyGeometry.faces[ 1 ].vertexColors.push( light, light, light );
                pyGeometry.faceVertexUvs[ 0 ][ 0 ][ 1 ].y = 0.5;
                pyGeometry.faceVertexUvs[ 0 ][ 1 ][ 0 ].y = 0.5;
                pyGeometry.faceVertexUvs[ 0 ][ 1 ][ 1 ].y = 0.5;
                pyGeometry.applyMatrix( matrix.makeRotationX( - Math.PI / 2 ) );
                pyGeometry.applyMatrix( matrix.makeTranslation( 0, 50, 0 ) );

                var py2Geometry = new THREE.PlaneGeometry( 100, 100 );
                py2Geometry.faces[ 0 ].vertexColors.push( light, light, light );
                py2Geometry.faces[ 1 ].vertexColors.push( light, light, light );
                py2Geometry.faceVertexUvs[ 0 ][ 0 ][ 1 ].y = 0.5;
                py2Geometry.faceVertexUvs[ 0 ][ 1 ][ 0 ].y = 0.5;
                py2Geometry.faceVertexUvs[ 0 ][ 1 ][ 1 ].y = 0.5;
                py2Geometry.applyMatrix( matrix.makeRotationX( - Math.PI / 2 ) );
                py2Geometry.applyMatrix( matrix.makeRotationY( Math.PI / 2 ) );
                py2Geometry.applyMatrix( matrix.makeTranslation( 0, 50, 0 ) );

                var pzGeometry = new THREE.PlaneGeometry( 100, 100 );
                pzGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                pzGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                pzGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                pzGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                pzGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                pzGeometry.applyMatrix( matrix.makeTranslation( 0, 0, 50 ) );

                var nzGeometry = new THREE.PlaneGeometry( 100, 100 );
                nzGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                nzGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                nzGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                nzGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                nzGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                nzGeometry.applyMatrix( matrix.makeRotationY( Math.PI ) );
                nzGeometry.applyMatrix( matrix.makeTranslation( 0, 0, - 50 ) );

                //

                var geometry = new THREE.Geometry();
                var dummy = new THREE.Mesh();

                for ( var z = 0; z < worldDepth; z ++ ) {

                    for ( var x = 0; x < worldWidth; x ++ ) {

                        var h = getY( x, z );

                        matrix.makeTranslation(
                            x * 100 - worldHalfWidth * 100,
                            h * 100,
                            z * 100 - worldHalfDepth * 100
                        );

                        var px = getY( x + 1, z );
                        var nx = getY( x - 1, z );
                        var pz = getY( x, z + 1 );
                        var nz = getY( x, z - 1 );

                        var pxpz = getY( x + 1, z + 1 );
                        var nxpz = getY( x - 1, z + 1 );
                        var pxnz = getY( x + 1, z - 1 );
                        var nxnz = getY( x - 1, z - 1 );

                        var a = nx > h || nz > h || nxnz > h ? 0 : 1;
                        var b = nx > h || pz > h || nxpz > h ? 0 : 1;
                        var c = px > h || pz > h || pxpz > h ? 0 : 1;
                        var d = px > h || nz > h || pxnz > h ? 0 : 1;

                        if ( a + c > b + d ) {

                            var colors = py2Geometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = b === 0 ? shadow : light;
                            colors[ 1 ] = c === 0 ? shadow : light;
                            colors[ 2 ] = a === 0 ? shadow : light;

                            var colors = py2Geometry.faces[ 1 ].vertexColors;
                            colors[ 0 ] = c === 0 ? shadow : light;
                            colors[ 1 ] = d === 0 ? shadow : light;
                            colors[ 2 ] = a === 0 ? shadow : light;
                            
                            geometry.merge( py2Geometry, matrix );

                        } else {

                            var colors = pyGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = a === 0 ? shadow : light;
                            colors[ 1 ] = b === 0 ? shadow : light;
                            colors[ 2 ] = d === 0 ? shadow : light;

                            var colors = pyGeometry.faces[ 1 ].vertexColors;
                            colors[ 0 ] = b === 0 ? shadow : light;
                            colors[ 1 ] = c === 0 ? shadow : light;
                            colors[ 2 ] = d === 0 ? shadow : light;
                            
                            geometry.merge( pyGeometry, matrix );

                        }

                        if ( ( px != h && px != h + 1 ) || x == 0 ) {

                            var colors = pxGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = pxpz > px && x > 0 ? shadow : light;
                            colors[ 2 ] = pxnz > px && x > 0 ? shadow : light;

                            var colors = pxGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = pxnz > px && x > 0 ? shadow : light;

                            geometry.merge( pxGeometry, matrix );

                        }

                        if ( ( nx != h && nx != h + 1 ) || x == worldWidth - 1 ) {

                            var colors = nxGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = nxnz > nx && x < worldWidth - 1 ? shadow : light;
                            colors[ 2 ] = nxpz > nx && x < worldWidth - 1 ? shadow : light;

                            var colors = nxGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = nxpz > nx && x < worldWidth - 1 ? shadow : light;

                            geometry.merge( nxGeometry, matrix );

                        }

                        if ( ( pz != h && pz != h + 1 ) || z == worldDepth - 1 ) {

                            var colors = pzGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = nxpz > pz && z < worldDepth - 1 ? shadow : light;
                            colors[ 2 ] = pxpz > pz && z < worldDepth - 1 ? shadow : light;

                            var colors = pzGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = pxpz > pz && z < worldDepth - 1 ? shadow : light;

                            geometry.merge( pzGeometry, matrix );

                        }

                        if ( ( nz != h && nz != h + 1 ) || z == 0 ) {

                            var colors = nzGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = pxnz > nz && z > 0 ? shadow : light;
                            colors[ 2 ] = nxnz > nz && z > 0 ? shadow : light;

                            var colors = nzGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = nxnz > nz && z > 0 ? shadow : light;

                            geometry.merge( nzGeometry, matrix );

                        }

                    }

                }

                var texture = THREE.ImageUtils.loadTexture( 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAgCAMAAAAsVwj+AAABv1BMVEUcQwAiTgElVAEqVgA5YgJJbQNQcghffgsnVAE0YQFxWjNxWTN2XzptWDVwVzJxVzMiUQBBbQN1XjloUC2AZUGAaEGNcUlMORcgUABRbgZVRQhWQR1YRiJ1XjVfRyVfTCd8YkF8Yz5/ZD8+KweAZUKAZURjTCeAaESMcUlnTy2OdEqQdk1SOhlTPxxTQSJTRAhUPBxURQhUdwk3Lgc5MxVWRQdWRidXQyJXSghXTykwLRBZRSFbTA5cRiddRyddTC5eRyheSyZeSygyLRI+Lgc+OhZgTChhTCdiUwxALgdjTidmTycpIwdnUC1nUDBCPCZoUS1oVC5pUy5pVxZqUy1rUixrUy1rVTBtVDJtVjJDMBVvVzNvWTNFNwdwWDJwWDhwWzhFPQdGQCdHNRJzWzNzWzt0XDpHNRVHPgd1XjtJNA92Yjx5YTl6Yzx7Yzs1YQFLRRt8ZEE2Lgd/ZURMOhdMOhpNNxZNRQdNRyiBa0ODZUGDaUGFbD+GbUSHbUeIbEOIbESIbEWIbUSIbUWIbkWJbkWJcUmKbUiLcUdPOheMckiNcUdQRwiNckqNdEmNdEqNdE02MSWPdUk3KAeVeFD3vhDZAAABm0lEQVR4XkWQU69mQRBFy330Gdc2xrZt27Zt2/ODp07uw2R3qpOVnZVKQTAyf6TGyKYIqEymLOIDhRRQzJQssAnmAQpBhM28Z+JFEENDUnURmRiDiUdJmP3LHYrEjHmERCiA641MjYRMCAnYuXvYKbOKgk7tQRpUObCBoGLAvC7IzoE1mKpwblJSAnJHQNexICkbsCtNBUUUXcVAZsZKFNTUnQRIZChqYt4XFm/8v0dUmbpHa4Vy040Io1YHXIkdzY4qEa5bHDloa4OoHMdlhPjrnyiCmzEuQvy142K8EOuH5pZhaRT3Pzi9cd6M8vWHj+qbbkNp66lve2aNvjuwpmPOWG3/MXi6tr3x+Mnv5vT2s0l1e0sJ1p9Jr355WV12olkfnry3oAXSnstZdmFaczwdLnkyaGRDd+f/SAqNFxODxeJQLwx+Hh/dVe361N3V7L/fMbMGEx+//327c0PPlTTtO1rrWwVj7589L3QfWZm9er383J2fCayuLikkh1d0bv4wsu1N78kEkuN7dw9s6bw2UBw5eGnfrfP/AEXsNS9OBYAmAAAAAElFTkSuQmCC' );
                texture.magFilter = THREE.NearestFilter;
                texture.minFilter = THREE.LinearMipMapLinearFilter;

                var mesh = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { map: texture, ambient: 0xbbbbbb, vertexColors: THREE.VertexColors } ) );
                scene.add( mesh );

                var ambientLight = new THREE.AmbientLight( 0xcccccc );
                scene.add( ambientLight );

                var directionalLight = new THREE.DirectionalLight( 0xffffff, 2 );
                directionalLight.position.set( 1, 1, 0.5 ).normalize();
                scene.add( directionalLight );

                renderer = new THREE.WebGLRenderer();
                renderer.setClearColor( 0xffffff );
                renderer.setSize( window.innerWidth, window.innerHeight );

                container.innerHTML = "";

                container.appendChild( renderer.domElement );

                stats = new Stats();
                stats.domElement.style.position = 'absolute';
                stats.domElement.style.top = '0px';
                container.appendChild( stats.domElement );

                //

                window.addEventListener( 'resize', onWindowResize, false );

            }

            function onWindowResize() {

                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();

                renderer.setSize( window.innerWidth, window.innerHeight );

                controls.handleResize();

            }

            function loadTexture( path, callback ) {

                var image = new Image();

                image.onload = function () { callback(); };
                image.src = path;

                return image;

            }

            function generateHeight( width, height ) {

                var data = [], perlin = new ImprovedNoise(),
                size = width * height, quality = 2, z = Math.random() * 100;

                for ( var j = 0; j < 4; j ++ ) {

                    if ( j == 0 ) for ( var i = 0; i < size; i ++ ) data[ i ] = 0;

                    for ( var i = 0; i < size; i ++ ) {

                        var x = i % width, y = ( i / width ) | 0;
                        data[ i ] += perlin.noise( x / quality, y / quality, z ) * quality;

                    }

                    quality *= 4

                }

                return data;

            }

            function getY( x, z ) {

                return ( data[ x + z * worldWidth ] * 0.2 ) | 0;

            }

            //

            function animate() {

                requestAnimationFrame( animate );

                render();
                stats.update();

            }

            function render() {

                controls.update( clock.getDelta() );
                renderer.render( scene, camera );

            }
            body {
                color: #61443e;
                font-family:Monospace;
                font-size:13px;
                text-align:center;

                /* background-color: #bfd1e5; */
                background-color: #ffffff;
                margin: 0px;
                overflow: hidden;
            }

            a { color: #a06851; }

            #info {
                position: absolute;
                top: 0px; width: 100%;
                padding: 5px;
            }

            #oldie {
                background:rgb(100,0,0) !important;
                color:#fff !important;
                margin-top:10em !important;
            }
            #oldie a { color:#fff }
        <div id="container"><br /><br /><br /><br /><br />Generating world...</div>
        <div id="info">
            <a href="http://threejs.org" target="_blank">three.js</a> - <a href="http://www.minecraft.net/" target="_blank">minecraft</a> demo [ambient occlusion]. featuring <a href="http://painterlypack.net/" target="_blank">painterly pack</a><br />(left click: forward, right click: backward)
        </div>

        <script src="https://threejs.org/build/three.min.js"></script>

        <script src="https://threejs.org/examples/js/controls/FirstPersonControls.js"></script>

        <script src="https://threejs.org/examples/js/ImprovedNoise.js"></script>

        <script src="https://threejs.org/examples/js/Detector.js"></script>
        <script src="https://threejs.org/examples/js/libs/stats.min.js"></script>

        <script>

        </script>
Source Link
Camilo Martin
  • 1.3k
  • 7
  • 17

Let's see if this can handle WebGL :D

            if ( ! Detector.webgl ) {

                Detector.addGetWebGLMessage();
                document.getElementById( 'container' ).innerHTML = "";

            }

            var fogExp2 = true;

            var container, stats;

            var camera, controls, scene, renderer;

            var mesh, mat;

            var worldWidth = 200, worldDepth = 200,
            worldHalfWidth = worldWidth / 2, worldHalfDepth = worldDepth / 2,
            data = generateHeight( worldWidth, worldDepth );

            var clock = new THREE.Clock();

            init();
            animate();

            function init() {

                container = document.getElementById( 'container' );

                camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 20000 );
                camera.position.y = getY( worldHalfWidth, worldHalfDepth ) * 100 + 100;

                controls = new THREE.FirstPersonControls( camera );

                controls.movementSpeed = 1000;
                controls.lookSpeed = 0.125;
                controls.lookVertical = true;
                controls.constrainVertical = true;
                controls.verticalMin = 1.1;
                controls.verticalMax = 2.2;

                scene = new THREE.Scene();
                scene.fog = new THREE.FogExp2( 0xffffff, 0.00015 );

                // sides
                
                var light = new THREE.Color( 0xffffff );
                var shadow = new THREE.Color( 0x505050 );

                var matrix = new THREE.Matrix4();

                var pxGeometry = new THREE.PlaneGeometry( 100, 100 );
                pxGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                pxGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                pxGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                pxGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                pxGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                pxGeometry.applyMatrix( matrix.makeRotationY( Math.PI / 2 ) );
                pxGeometry.applyMatrix( matrix.makeTranslation( 50, 0, 0 ) );

                var nxGeometry = new THREE.PlaneGeometry( 100, 100 );
                nxGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                nxGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                nxGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                nxGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                nxGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                nxGeometry.applyMatrix( matrix.makeRotationY( - Math.PI / 2 ) );
                nxGeometry.applyMatrix( matrix.makeTranslation( - 50, 0, 0 ) );

                var pyGeometry = new THREE.PlaneGeometry( 100, 100 );
                pyGeometry.faces[ 0 ].vertexColors.push( light, light, light );
                pyGeometry.faces[ 1 ].vertexColors.push( light, light, light );
                pyGeometry.faceVertexUvs[ 0 ][ 0 ][ 1 ].y = 0.5;
                pyGeometry.faceVertexUvs[ 0 ][ 1 ][ 0 ].y = 0.5;
                pyGeometry.faceVertexUvs[ 0 ][ 1 ][ 1 ].y = 0.5;
                pyGeometry.applyMatrix( matrix.makeRotationX( - Math.PI / 2 ) );
                pyGeometry.applyMatrix( matrix.makeTranslation( 0, 50, 0 ) );

                var py2Geometry = new THREE.PlaneGeometry( 100, 100 );
                py2Geometry.faces[ 0 ].vertexColors.push( light, light, light );
                py2Geometry.faces[ 1 ].vertexColors.push( light, light, light );
                py2Geometry.faceVertexUvs[ 0 ][ 0 ][ 1 ].y = 0.5;
                py2Geometry.faceVertexUvs[ 0 ][ 1 ][ 0 ].y = 0.5;
                py2Geometry.faceVertexUvs[ 0 ][ 1 ][ 1 ].y = 0.5;
                py2Geometry.applyMatrix( matrix.makeRotationX( - Math.PI / 2 ) );
                py2Geometry.applyMatrix( matrix.makeRotationY( Math.PI / 2 ) );
                py2Geometry.applyMatrix( matrix.makeTranslation( 0, 50, 0 ) );

                var pzGeometry = new THREE.PlaneGeometry( 100, 100 );
                pzGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                pzGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                pzGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                pzGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                pzGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                pzGeometry.applyMatrix( matrix.makeTranslation( 0, 0, 50 ) );

                var nzGeometry = new THREE.PlaneGeometry( 100, 100 );
                nzGeometry.faces[ 0 ].vertexColors.push( light, shadow, light );
                nzGeometry.faces[ 1 ].vertexColors.push( shadow, shadow, light );
                nzGeometry.faceVertexUvs[ 0 ][ 0 ][ 0 ].y = 0.5;
                nzGeometry.faceVertexUvs[ 0 ][ 0 ][ 2 ].y = 0.5;
                nzGeometry.faceVertexUvs[ 0 ][ 1 ][ 2 ].y = 0.5;
                nzGeometry.applyMatrix( matrix.makeRotationY( Math.PI ) );
                nzGeometry.applyMatrix( matrix.makeTranslation( 0, 0, - 50 ) );

                //

                var geometry = new THREE.Geometry();
                var dummy = new THREE.Mesh();

                for ( var z = 0; z < worldDepth; z ++ ) {

                    for ( var x = 0; x < worldWidth; x ++ ) {

                        var h = getY( x, z );

                        matrix.makeTranslation(
                            x * 100 - worldHalfWidth * 100,
                            h * 100,
                            z * 100 - worldHalfDepth * 100
                        );

                        var px = getY( x + 1, z );
                        var nx = getY( x - 1, z );
                        var pz = getY( x, z + 1 );
                        var nz = getY( x, z - 1 );

                        var pxpz = getY( x + 1, z + 1 );
                        var nxpz = getY( x - 1, z + 1 );
                        var pxnz = getY( x + 1, z - 1 );
                        var nxnz = getY( x - 1, z - 1 );

                        var a = nx > h || nz > h || nxnz > h ? 0 : 1;
                        var b = nx > h || pz > h || nxpz > h ? 0 : 1;
                        var c = px > h || pz > h || pxpz > h ? 0 : 1;
                        var d = px > h || nz > h || pxnz > h ? 0 : 1;

                        if ( a + c > b + d ) {

                            var colors = py2Geometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = b === 0 ? shadow : light;
                            colors[ 1 ] = c === 0 ? shadow : light;
                            colors[ 2 ] = a === 0 ? shadow : light;

                            var colors = py2Geometry.faces[ 1 ].vertexColors;
                            colors[ 0 ] = c === 0 ? shadow : light;
                            colors[ 1 ] = d === 0 ? shadow : light;
                            colors[ 2 ] = a === 0 ? shadow : light;
                            
                            geometry.merge( py2Geometry, matrix );

                        } else {

                            var colors = pyGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = a === 0 ? shadow : light;
                            colors[ 1 ] = b === 0 ? shadow : light;
                            colors[ 2 ] = d === 0 ? shadow : light;

                            var colors = pyGeometry.faces[ 1 ].vertexColors;
                            colors[ 0 ] = b === 0 ? shadow : light;
                            colors[ 1 ] = c === 0 ? shadow : light;
                            colors[ 2 ] = d === 0 ? shadow : light;
                            
                            geometry.merge( pyGeometry, matrix );

                        }

                        if ( ( px != h && px != h + 1 ) || x == 0 ) {

                            var colors = pxGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = pxpz > px && x > 0 ? shadow : light;
                            colors[ 2 ] = pxnz > px && x > 0 ? shadow : light;

                            var colors = pxGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = pxnz > px && x > 0 ? shadow : light;

                            geometry.merge( pxGeometry, matrix );

                        }

                        if ( ( nx != h && nx != h + 1 ) || x == worldWidth - 1 ) {

                            var colors = nxGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = nxnz > nx && x < worldWidth - 1 ? shadow : light;
                            colors[ 2 ] = nxpz > nx && x < worldWidth - 1 ? shadow : light;

                            var colors = nxGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = nxpz > nx && x < worldWidth - 1 ? shadow : light;

                            geometry.merge( nxGeometry, matrix );

                        }

                        if ( ( pz != h && pz != h + 1 ) || z == worldDepth - 1 ) {

                            var colors = pzGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = nxpz > pz && z < worldDepth - 1 ? shadow : light;
                            colors[ 2 ] = pxpz > pz && z < worldDepth - 1 ? shadow : light;

                            var colors = pzGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = pxpz > pz && z < worldDepth - 1 ? shadow : light;

                            geometry.merge( pzGeometry, matrix );

                        }

                        if ( ( nz != h && nz != h + 1 ) || z == 0 ) {

                            var colors = nzGeometry.faces[ 0 ].vertexColors;
                            colors[ 0 ] = pxnz > nz && z > 0 ? shadow : light;
                            colors[ 2 ] = nxnz > nz && z > 0 ? shadow : light;

                            var colors = nzGeometry.faces[ 1 ].vertexColors;
                            colors[ 2 ] = nxnz > nz && z > 0 ? shadow : light;

                            geometry.merge( nzGeometry, matrix );

                        }

                    }

                }

                var texture = THREE.ImageUtils.loadTexture( 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAgCAMAAAAsVwj+AAABv1BMVEUcQwAiTgElVAEqVgA5YgJJbQNQcghffgsnVAE0YQFxWjNxWTN2XzptWDVwVzJxVzMiUQBBbQN1XjloUC2AZUGAaEGNcUlMORcgUABRbgZVRQhWQR1YRiJ1XjVfRyVfTCd8YkF8Yz5/ZD8+KweAZUKAZURjTCeAaESMcUlnTy2OdEqQdk1SOhlTPxxTQSJTRAhUPBxURQhUdwk3Lgc5MxVWRQdWRidXQyJXSghXTykwLRBZRSFbTA5cRiddRyddTC5eRyheSyZeSygyLRI+Lgc+OhZgTChhTCdiUwxALgdjTidmTycpIwdnUC1nUDBCPCZoUS1oVC5pUy5pVxZqUy1rUixrUy1rVTBtVDJtVjJDMBVvVzNvWTNFNwdwWDJwWDhwWzhFPQdGQCdHNRJzWzNzWzt0XDpHNRVHPgd1XjtJNA92Yjx5YTl6Yzx7Yzs1YQFLRRt8ZEE2Lgd/ZURMOhdMOhpNNxZNRQdNRyiBa0ODZUGDaUGFbD+GbUSHbUeIbEOIbESIbEWIbUSIbUWIbkWJbkWJcUmKbUiLcUdPOheMckiNcUdQRwiNckqNdEmNdEqNdE02MSWPdUk3KAeVeFD3vhDZAAABm0lEQVR4XkWQU69mQRBFy330Gdc2xrZt27Zt2/ODp07uw2R3qpOVnZVKQTAyf6TGyKYIqEymLOIDhRRQzJQssAnmAQpBhM28Z+JFEENDUnURmRiDiUdJmP3LHYrEjHmERCiA641MjYRMCAnYuXvYKbOKgk7tQRpUObCBoGLAvC7IzoE1mKpwblJSAnJHQNexICkbsCtNBUUUXcVAZsZKFNTUnQRIZChqYt4XFm/8v0dUmbpHa4Vy040Io1YHXIkdzY4qEa5bHDloa4OoHMdlhPjrnyiCmzEuQvy142K8EOuH5pZhaRT3Pzi9cd6M8vWHj+qbbkNp66lve2aNvjuwpmPOWG3/MXi6tr3x+Mnv5vT2s0l1e0sJ1p9Jr355WV12olkfnry3oAXSnstZdmFaczwdLnkyaGRDd+f/SAqNFxODxeJQLwx+Hh/dVe361N3V7L/fMbMGEx+//327c0PPlTTtO1rrWwVj7589L3QfWZm9er383J2fCayuLikkh1d0bv4wsu1N78kEkuN7dw9s6bw2UBw5eGnfrfP/AEXsNS9OBYAmAAAAAElFTkSuQmCC' );
                texture.magFilter = THREE.NearestFilter;
                texture.minFilter = THREE.LinearMipMapLinearFilter;

                var mesh = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { map: texture, ambient: 0xbbbbbb, vertexColors: THREE.VertexColors } ) );
                scene.add( mesh );

                var ambientLight = new THREE.AmbientLight( 0xcccccc );
                scene.add( ambientLight );

                var directionalLight = new THREE.DirectionalLight( 0xffffff, 2 );
                directionalLight.position.set( 1, 1, 0.5 ).normalize();
                scene.add( directionalLight );

                renderer = new THREE.WebGLRenderer();
                renderer.setClearColor( 0xffffff );
                renderer.setSize( window.innerWidth, window.innerHeight );

                container.innerHTML = "";

                container.appendChild( renderer.domElement );

                stats = new Stats();
                stats.domElement.style.position = 'absolute';
                stats.domElement.style.top = '0px';
                container.appendChild( stats.domElement );

                //

                window.addEventListener( 'resize', onWindowResize, false );

            }

            function onWindowResize() {

                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();

                renderer.setSize( window.innerWidth, window.innerHeight );

                controls.handleResize();

            }

            function loadTexture( path, callback ) {

                var image = new Image();

                image.onload = function () { callback(); };
                image.src = path;

                return image;

            }

            function generateHeight( width, height ) {

                var data = [], perlin = new ImprovedNoise(),
                size = width * height, quality = 2, z = Math.random() * 100;

                for ( var j = 0; j < 4; j ++ ) {

                    if ( j == 0 ) for ( var i = 0; i < size; i ++ ) data[ i ] = 0;

                    for ( var i = 0; i < size; i ++ ) {

                        var x = i % width, y = ( i / width ) | 0;
                        data[ i ] += perlin.noise( x / quality, y / quality, z ) * quality;

                    }

                    quality *= 4

                }

                return data;

            }

            function getY( x, z ) {

                return ( data[ x + z * worldWidth ] * 0.2 ) | 0;

            }

            //

            function animate() {

                requestAnimationFrame( animate );

                render();
                stats.update();

            }

            function render() {

                controls.update( clock.getDelta() );
                renderer.render( scene, camera );

            }
            body {
                color: #61443e;
                font-family:Monospace;
                font-size:13px;
                text-align:center;

                /* background-color: #bfd1e5; */
                background-color: #ffffff;
                margin: 0px;
                overflow: hidden;
            }

            a { color: #a06851; }

            #info {
                position: absolute;
                top: 0px; width: 100%;
                padding: 5px;
            }

            #oldie {
                background:rgb(100,0,0) !important;
                color:#fff !important;
                margin-top:10em !important;
            }
            #oldie a { color:#fff }
        <div id="container"><br /><br /><br /><br /><br />Generating world...</div>
        <div id="info">
            <a href="http://threejs.org" target="_blank">three.js</a> - <a href="http://www.minecraft.net/" target="_blank">minecraft</a> demo [ambient occlusion]. featuring <a href="http://painterlypack.net/" target="_blank">painterly pack</a><br />(left click: forward, right click: backward)
        </div>

        <script src="http://threejs.org/build/three.min.js"></script>

        <script src="http://threejs.org/examples/js/controls/FirstPersonControls.js"></script>

        <script src="http://threejs.org/examples/js/ImprovedNoise.js"></script>

        <script src="http://threejs.org/examples/js/Detector.js"></script>
        <script src="http://threejs.org/examples/js/libs/stats.min.js"></script>

        <script>

        </script>

Spoiler: yes it can.

Taken from here.

Post Made Community Wiki by Camilo Martin