Hue spiral

by EliasHasle

HTML

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

CSS

body {
  background-color: #000;
  margin: 0px;
  overflow: hidden;
}

JavaScript

var points, renderer, scene, camera, controls;

init();
requestAnimationFrame(animate);

function init() {

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

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

  // camera
  camera = new THREE.OrthographicCamera(-0.5 * window.innerWidth, 0.5 * window.innerHeight, 0.5 * window.innerWidth, -0.5 * window.innerHeight);
  camera.position.set(0, 0, 1);

  // geometry
  var geometry = new THREE.BufferGeometry();
  const N = 1;
  let pa = new Float32Array(3 * N).fill(0);
  geometry.addAttribute("position", new THREE.BufferAttribute(pa, 3));
  geometry.attributes.position.needsUpdate = true;

  // material
  var material = new THREE.RawShaderMaterial({
    vertexShader: `
      uniform mat4 viewMatrix;
      uniform mat4 projectionMatrix;
      uniform float radius;
      attribute vec3 position;
      void main() {
      	gl_Position = projectionMatrix*viewMatrix*vec4(position,1.);
      	gl_PointSize = 2.*radius;
      }
      `,
    fragmentShader: `
      #define PI 3.141592654
      precision highp float;
      uniform float arms;
      uniform float turns;
      uniform float frequency;
      uniform float time;
      
    vec3 h2rgb(float h) {
      vec3 p = abs(fract(vec3(h)+vec3(1.,2./3.,1./3.))*6.-vec3(3.));
      return clamp(p - vec3(1.), 0.,1.);
    }
      
      void main() {
        vec2 pc = 2.*gl_PointCoord.xy-vec2(1.);
      	float r = length(pc);
        if (r > 1.) {
        	discard;
        }
        float theta = atan(pc.x, pc.y);
        float alpha = theta + turns*2.*PI*r + 2.*PI*frequency*time;
        gl_FragColor = vec4(h2rgb(mod(arms*alpha/(2.*PI),1.)),1.);
      }
      `,
    uniforms: {
      radius: {
        value: 320
      },
      arms: {
        value: 5
      },
      turns: {
        value: 2
      },
      frequency: {value: 1.},
      time: {
       ...