<!DOCTYPE html>
<html lang="en">
<head>
    <title>three.js webgl - shader [Monjori]</title>
    <meta charset="utf-8">
    <script id="vertexShader" type="x-shader/x-vertex">
        varying vec2 vUv;

        void main()    {
            vUv = uv;
            gl_Position = vec4(position, 1.0);
        }
    </script>
    <script id="fragmentShader" type="x-shader/x-fragment">
        #ifdef GL_FRAGMENT_PRECISION_HIGH
        precision highp float;
        #else
        precision mediump float;
        #endif

        uniform float iTime;
        uniform vec2 iMouse;
        uniform vec2 iResolution;
        uniform sampler2D iChannel0;

        vec2 GetGradient(vec2 intPos, float t) {
            float rand = texture(iChannel0, intPos / 64.0).r * 4.0;
            float angle = 6.283185 * rand + 4.0 * t * rand;
            return vec2(cos(angle), sin(angle));
        }

        float Pseudo3dNoise(vec3 pos) {
            vec2 i = floor(pos.xy);
            vec2 f = pos.xy - i;
            vec2 blend = f * f * (3.0 -(2.0 * f));
            float noiseVal =
            mix(
            mix(
            dot(GetGradient(i + vec2(0, 0), pos.z), f - vec2(0, 0)),
            dot(GetGradient(i + vec2(1, 0), pos.z), f - vec2(1, 0)),
            blend.x),
            mix(
            dot(GetGradient(i + vec2(0, 1), pos.z), f - vec2(0, 1)),
            dot(GetGradient(i + vec2(1, 1), pos.z), f - vec2(1, 1)),
            blend.x),
            blend.y
            );
            return noiseVal / 0.7;// normalize to about [-1..1]
        }

        void mainImage(out vec4 fragColor, in vec2 fragCoord) {
            vec2 uv = fragCoord.xy / iResolution.y;

            float time = iTime * (iTime * 0.1);
            vec2 uvm = iMouse.xy / iResolution.y;
            float noiseVal = 0.5 + 0.5 * Pseudo3dNoise(vec3(uv *6.0, time/10.));

            fragColor.rgb = vec3( 0.8+ 0.2*sin(noiseVal * time + (sin(time) * time / 10.)));
        }

        void main() {
            mainImage(gl_FragColor, gl_FragCoord.xy);
        }
    </script>
</head>

<body>
<div id="container"></div>

<script type="module">
			import * as THREE from 'https://unpkg.com/three/build/three.module.js';

			let camera, scene, renderer;
			let uniforms;
			let texture;
			init();
			animate();

			function init() {
				const container = document.getElementById( 'container' );
				camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
				scene = new THREE.Scene();
				const geometry = new THREE.PlaneGeometry( 2, 2 );

                const loader = new THREE.TextureLoader();
                const texture = loader.load('noise.png');
                texture.wrapS = THREE.RepeatWrapping;
                texture.wrapT = THREE.RepeatWrapping;

                let quality = 1
				uniforms = {
					iTime: { value: 1.0 },
					iResolution: { value: new THREE.Vector2( window.innerWidth / quality, window.innerHeight / quality ) },
					iMouse: { value: new THREE.Vector2(0.0,0.0) },
					iChannel0: { value: texture },
				};

				const material = new THREE.ShaderMaterial( {
					uniforms: uniforms,
					vertexShader: document.getElementById( 'vertexShader' ).textContent,
					fragmentShader: document.getElementById( 'fragmentShader' ).textContent
				} );

				const mesh = new THREE.Mesh( geometry, material );
				scene.add( mesh );
				renderer = new THREE.WebGLRenderer();
				renderer.setPixelRatio( window.devicePixelRatio );
				container.appendChild( renderer.domElement );
				onWindowResize();
				window.addEventListener( 'resize', onWindowResize );
				document.addEventListener( 'pointermove', onPointerMove);
			}

			function onPointerMove(event) {
                var clientX = event.clientX;
                var clientY = event.clientY;

                var mouseX = clientX / window.innerWidth;
                var mouseY = 1 - clientY / window.innerHeight;

                uniforms[ 'iMouse' ].value = new THREE.Vector2(mouseX, mouseY);
			}

			function onWindowResize() {
				renderer.setSize( window.innerWidth, window.innerHeight );
			}


			function animate() {
				window.requestAnimationFrame( animate );
				uniforms[ 'iTime' ].value = performance.now() / 1000;
				renderer.render( scene, camera );
			}



</script>
</body>
</html>