<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>