<html>
  <body>
  <div id="world"></div>  
  </body>
</html>
html, body {
  margin: 0;
}

#world {
  position: absolute;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: linear-gradient(#e4e0ba, #f7d9aa);
  
}
// Low poly water from three.js Plane.
// Small edit of source code from original tutorial: https://tympanus.net/codrops/2016/04/26/the-aviator-animating-basic-3d-scene-threejs/

var scene, camera, fieldOfView, aspectRatio, nearPlane, farPlane, HEIGHT, WIDTH, renderer, container;

function createScene() {
  HEIGHT = window.innerHeight;
  WIDTH = window.innerWidth;

  scene = new THREE.Scene();

  scene.fog = new THREE.Fog(0xf7d9aa, 100, 950);

  aspectRatio = WIDTH / HEIGHT;
  fieldOfView = 60;
  nearPlane = 1;
  farPlane = 10000;
  camera = new THREE.PerspectiveCamera(fieldOfView, aspectRatio, nearPlane, farPlane);

  camera.position.x = 0;
  camera.position.z = 250;
  camera.position.y = 250;

  renderer = new THREE.WebGLRenderer({
    alpha: true,
  });


  renderer.setSize(WIDTH, HEIGHT);

  renderer.shadowMap.enabled = true;

  container = document.getElementById('world');
  container.appendChild(renderer.domElement);


  window.addEventListener('resize', handleWindowResize, false);
}

function handleWindowResize() {
  HEIGHT = window.innerHeight;
  WIDTH = window.innerWidth;
  renderer.setSize(WIDTH, HEIGHT);
  camera.aspect = WIDTH / HEIGHT;
  camera.updateProjectionMatrix();
}

var hemisphereLight, shadowLight;

function createLights() {
  hemisphereLight = new THREE.HemisphereLight(0xaaaaaa, 0x000000, .9);

  shadowLight = new THREE.DirectionalLight(0xffffff, .9);

  shadowLight.position.set(-150, 350, 350);

  shadowLight.castShadow = true;

  shadowLight.shadow.camera.left = -400;
  shadowLight.shadow.camera.right = 400;
  shadowLight.shadow.camera.top = 400;
  shadowLight.shadow.camera.bottom = -400;
  shadowLight.shadow.camera.near = 1;
  shadowLight.shadow.camera.far = 1000;

  shadowLight.shadow.mapSize.width = 2048;
  shadowLight.shadow.mapSize.height = 2048;

  scene.add(hemisphereLight);
  scene.add(shadowLight);
}

const Ocean = function () {
  let geom = new THREE.PlaneGeometry(350, 250, 10, 10);

  geom.applyMatrix(new THREE.Matrix4().makeRotationX(-Math.PI / 2));

  geom.mergeVertices();

  let l = geom.vertices.length;

  this.waves = [];
  for (var i = 0; i < l; i++) {
    const v = geom.vertices[i];

    this.waves.push({
      y: v.y,
      x: v.x,
      z: v.z,
      ang: Math.random() * Math.PI * 2,
      speed: 0.016 + Math.random() * 0.032
    });
  }

  let mat = new THREE.MeshPhongMaterial({
    color: 0x68c3c0,
    transparent: true,
    // opacity: .8,
    flatShading: THREE.FlatShading,
  });

  this.mesh = new THREE.Mesh(geom, mat);

  this.mesh.receiveShadow = true;

}

Ocean.prototype.moveWaves = function () {

  const verts = this.mesh.geometry.vertices;
  const l = verts.length;

  for (var i = 0; i < l; i++) {
    const v = verts[i];

    const vprops = this.waves[i];

    v.x = vprops.x + Math.cos(vprops.ang);
    v.y = vprops.y + Math.sin(vprops.ang)*2;

    vprops.ang += vprops.speed;
  }

  this.mesh.geometry.verticesNeedUpdate = true;

}

var ocean;
function createOcean() {
  ocean = new Ocean();

  ocean.mesh.position.y = 200;
  ocean.mesh.position.z = -35;

  scene.add(ocean.mesh);
}

function loop() {
  ocean.moveWaves();

  renderer.render(scene, camera);

  requestAnimationFrame(loop);
}

function init() {
  createScene();

  createLights();

  createOcean();

  loop();
}

window.addEventListener('load', init, false);
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/three.js/109/three.min.js