Grid Plane Waves

by Cody Bennett

CSS

body {
  margin: 0;
}

canvas {
  display: block;
}

JavaScript

import * as THREE from 'https://unpkg.com/three/build/three.module.js';

Object.assign(THREE.PlaneBufferGeometry.prototype, {
  toGrid: function() {
    let segmentsX = this.parameters.widthSegments || 1;
    let segmentsY = this.parameters.heightSegments || 1;
    let indices = [];

    for (let i = 0; i < segmentsY + 1; i++) {
      let index11 = 0;
      let index12 = 0;

      for (let j = 0; j < segmentsX; j++) {
        index11 = (segmentsX + 1) * i + j;
        index12 = index11 + 1;

        let index21 = index11;
        let index22 = index11 + (segmentsX + 1);

        indices.push(index11, index12);

        if (index22 < ((segmentsX + 1) * (segmentsY + 1) - 1)) {
          indices.push(index21, index22);
        }
      }

      if ((index12 + segmentsX + 1) <= ((segmentsX + 1) * (segmentsY + 1) - 1)) {
        indices.push(index12, index12 + segmentsX + 1);
      }
    }

    this.setIndex(indices);

    return this;
  }
});

const renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 25, 200);

const scene = new THREE.Scene();

const planeGeometry = new THREE.PlaneBufferGeometry(500, 500, 100, 100).toGrid();
planeGeometry.rotateX(-Math.PI * 0.5);

const plane = new THREE.LineSegments(planeGeometry, new THREE.ShaderMaterial({
  uniforms: {
    color: {
      value: new THREE.Color("white")
    },
    opacity: {
      value: 0.75
    },
    time: {
      value: 0
    },
    amplitude: {
      value: 5
    },
    waveLength: {
      value: Math.PI * 10
    }
  },
  vertexShader: `
    uniform float size;
    uniform float time;
    uniform float amplitude;
    uniform float waveLength;
    varying float ampNormalized;

  	void main() {
      vec3 p = position;
      float wLength = 1. / waveLength;
      p.y = sin(position.x...