Three.js Time Tunnel

Dr Who style time tunnel with a cylinder and ShaderMaterial

HTML

<script src="https://rawgit.com/mrdoob/three.js/r76/build/three.min.js"></script>
<script src="https://cdn.rawgit.com/dataarts/dat.gui/v0.5.1/build/dat.gui.min.js"></script>
<script id="tunnelVertexShader" type="x-shader/x-vertex">
    varying vec3 vPosition;
    void main( void ) {
      vPosition = position;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
    }
  </script>

  <script id="tunnelFragmentShader" type="x-shader/x-fragment">
    varying vec3 vPosition;
    uniform vec3 color;
    uniform vec3 noiseScale;
    uniform float speed;
    uniform float time;
    uniform float intensity;

    //
    // Description : Array and textureless GLSL 2D/3D/4D simplex
    //               noise functions.
    //      Author : Ian McEwan, Ashima Arts.
    //  Maintainer : ijm
    //     Lastmod : 20110822 (ijm)
    //     License : Copyright (C) 2011 Ashima Arts. All rights reserved.
    //               Distributed under the MIT License. See LICENSE file.
    //               https://github.com/ashima/webgl-noise
    //

    vec4 mod289(vec4 x) {
      return x - floor(x * (1.0 / 289.0)) * 289.0; }

    float mod289(float x) {
      return x - floor(x * (1.0 / 289.0)) * 289.0; }

    vec4 permute(vec4 x) {
         return mod289(((x*34.0)+1.0)*x);
    }

    float permute(float x) {
         return mod289(((x*34.0)+1.0)*x);
    }

    vec4 taylorInvSqrt(vec4 r)
    {
      return 1.79284291400159 - 0.85373472095314 * r;
    }

    float taylorInvSqrt(float r)
    {
      return 1.79284291400159 - 0.85373472095314 * r;
    }

    vec4 grad4(float j, vec4 ip)
      {
      const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0);
      vec4 p,s;

      p.xyz = floor( fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0;
      p.w = 1.5 - dot(abs(p.xyz), ones.xyz);
      s = vec4(lessThan(p, vec4(0.0)));
      p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www;

      return p;
      }

    // (sqrt(5) - 1)/4 = F4, used once below
    #define F4 0.309016994374947451

 ...

CSS

body {
  margin: 0px;
  background-color: #000000;
}
canvas {
  display: block;
}

JavaScript

var camera, scene, renderer, mesh, material;
  var clock = new THREE.Clock();
  init();
  animate();

  function init(){
    // Renderer.
    renderer = new THREE.WebGLRenderer({antialias: true, alpha: true});
    //renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    // Add renderer to page
    document.body.appendChild(renderer.domElement);

    // Create camera.
    camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 100000);
    camera.position.z = 1500;

    // Create scene.
    scene = new THREE.Scene();

    // Create material
    var uniforms = {
        color: { type: "c", value: new THREE.Color(0xffffff) },
        noiseScale: { type: "v3", value: new THREE.Vector3(3000.0, 3000.0, 2000.0)},
        speed: { type: "f", value: 1000.0},
        time: { type:"f", value: 0.0},
        intensity: { type:"f", value: 3.0}
    };
    var vertexShader = document.getElementById('tunnelVertexShader').text;
    var fragmentShader = document.getElementById('tunnelFragmentShader').text;
    material = new THREE.ShaderMaterial(
      {
        uniforms : uniforms,
        vertexShader : vertexShader,
        fragmentShader : fragmentShader,
        side: THREE.BackSide
      });

    // Create cylinder and add to scene.
    // CylinderBufferGeometry(radiusTop, radiusBottom, height, radiusSegments, heightSegments, openEnded, thetaStart, thetaLength)
    var geometry = new THREE.CylinderBufferGeometry( 200, 100, 3000, 32, 16, true );
    mesh = new THREE.Mesh(geometry, material);
    // rotate 90 degrees
    mesh.rotation.x = (90 * Math.PI)/180;
    scene.add(mesh);

    // Add listener for window resize.
    window.addEventListener('resize', onWindowResize, false);

    // set up controls
    gui(uniforms);

  }

  function animate() {
    requestAnimationFrame(animate);
    //mesh.rotation.x += 0.01;
    material.uniforms.time.value = clock.getElapsedTime();
   ...