<script type="module"> import THREE from "https://esm.sh/three.js"; const container = document.getElementById("canvas-cont"); // Set up the scene, camera, and renderer const scene = new THREE.Scene(); const camera = new THREE.OrthographicCamera(-2, 2, 2, -2, 0.1, 100); const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); container.appendChild(renderer.domElement); // Create a plane geometry for the fractal const geometry = new THREE.PlaneGeometry(4, 4); // Create a custom shader material for the Julia set const material = new THREE.ShaderMaterial({ uniforms: { c: { value: new THREE.Vector2(0, 0) } }, vertexShader: ` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `, fragmentShader: ` uniform vec2 c; varying vec2 vUv; vec3 colorize(float t) { return vec3(0.5 * cos(1.5 * 3.14159 * t) + 0.5, 0.5 * sin(1.5 * 3.14159 * t) + 0.5, 0.5 * t + 0.5); } void main() { vec2 z = (vUv * 4.0 - 2.0); float n = 0.0; for (int i = 0; i < 100; i++) { z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + c; if (dot(z, z) > 4.0) { break; } n++; } float t = n / 100.0; vec3 color = colorize(t); gl_FragColor = vec4(color, 1.0); } ` }); // Create a mesh for the fractal and add it to the scene const fractal = new THREE.Mesh(geometry, material); scene.add(fractal); camera.position.z = 1; // Create an animate function to render the scene and update the fractal function animate(time) { requestAnimationFrame(animate); const elapsedTime = time * 0.0005; // Slower animation material.uniforms.c.value.x = 0.7885 * Math.cos(elapsedTime); material.uniforms.c.value.y = 0.7885 * Math.sin(elapsedTime); renderer.render(scene, camera); } animate(); </script> <div id="canvas-cont"></div>