<html>
  <head>
    <link href="./styles.css" rel="stylesheet" />
    <script type="importmap">
      {
        "imports": {
          "three": "https://cdn.jsdelivr.net/npm/three@0.174.0/build/three.module.js",
          "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.174.0/examples/jsm/"
        }
      }
    </script>
  </head>
  <body style="padding: 0; margin: 0">
    <script type="module">
      import { OrbitControls } from "three/addons/controls/OrbitControls.js";
      import { Scene, PerspectiveCamera, WebGLRenderer, GridHelper, AxesHelper, Color, PlaneGeometry, ShaderMaterial, Vector3, Vector4, DoubleSide, Mesh } from "three";

      var container, w, h, scene, camera, renderer, controls;

      document.addEventListener("DOMContentLoaded", () => {
        setup();

        const shaderMaterial = new ShaderMaterial({
          uniforms: {
            iMouse: { value: new Vector4(0, 0, 0, 1) },
            iTime: { value: 0 },
            iResolution: { value: new Vector3(w, h, 1) },
          },
          vertexShader: `
            varying vec2 vUv;
            void main() {
              vUv = uv;
              gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
            }
          `,
          fragmentShader: `
            uniform vec4 iMouse;
            uniform vec3 iResolution;
            uniform float iTime;
            varying vec2 vUv;
            
            // Author: Xor
            // URL: https://www.shadertoy.com/view/lXXXzS
            
            vec4 mainImage(vec2 fragCoord){
              //Scaled pixel coordinates
              vec2 p=fragCoord.xy/iResolution.y*6.;

              //8 wave passes
              for(float i=0.0; i<8.0;i++)
              {
                  //Add a simple sine wave with an offset and animation
                  p.x += sin(p.y+i+iTime*.3);
                  //Rotate and scale down
                  p *= mat2(6,-8,8,6)/8.;
              }

              //Pick a color using the turbulent coordinates
              return sin(p.xyxy*.3+vec4(0,1,2,3))*.5+.5;
            }
        

            void main() {
              vec4 fragColor = mainImage(vUv * iResolution.xy);
              gl_FragColor = vec4(fragColor.x, fragColor.y, fragColor.z, 1);
            }
          `,
          side: DoubleSide,
        });

        scene.add(new Mesh(new PlaneGeometry(), shaderMaterial));

        renderer.setAnimationLoop((t) => {
          shaderMaterial.uniforms.iTime.value = t / 1000;

          controls.update();
          renderer.render(scene, camera);
        });
      });

      function setup() {
        container = document.body;

        w = container.clientWidth;
        h = container.clientHeight;

        scene = new Scene();
        camera = new PerspectiveCamera(75, w / h, 0.1, 1000);
        renderer = new WebGLRenderer({ antialias: true });
        controls = new OrbitControls(camera, renderer.domElement);

        camera.position.set(5, 5, 5);
        camera.lookAt(0, 0, 0);
        camera.updateProjectionMatrix();

        renderer.localClippingEnabled = true;
        renderer.setSize(w, h);
        renderer.render(scene, camera);
        container.append(renderer.domElement);

        scene.add(new GridHelper(), new AxesHelper());

        window.addEventListener("resize", () => {
          w = container.clientWidth;
          h = container.clientHeight;

          camera.aspect = w / h;
          camera.updateProjectionMatrix();
          renderer.setSize(w, h);
        });
      }
    </script>
  </body>
</html>