Created
December 31, 2024 08:20
-
-
Save anon987654321/ed4303a9c8d350d0acdc5658a8ece315 to your computer and use it in GitHub Desktop.
"Shader Animation 16"
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <html lang="fr"> | |
| <head> | |
| <base href="." /> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Fibonacci GLSL</title> | |
| <link href="https://cdn.jsdelivr.net/npm/@fontsource/[email protected]/index.min.css" rel="stylesheet"> | |
| <link rel="stylesheet" href="styles.css"> | |
| </head> | |
| <body> | |
| <canvas id="canvas"></canvas> | |
| <a href="https://codepen.io/H-L-the-lessful" class="button-3d">MY WORK</a> | |
| <div class="credits">CODE by HL</div> | |
| <script type="module" src="script.js"></script> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import * as THREE from "https://cdn.skypack.dev/[email protected]"; | |
| let scene, camera, renderer; | |
| let time = 0; | |
| // Vertex Shader | |
| const vertexShader = ` | |
| varying vec2 vUv; | |
| varying vec3 vPosition; | |
| varying vec3 vNormal; | |
| void main() { | |
| vUv = uv; | |
| vPosition = position; | |
| vNormal = normal; | |
| gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); | |
| }`; | |
| // Fragment Shader | |
| const fragmentShader = ` | |
| #ifdef GL_ES | |
| precision highp float; | |
| #endif | |
| uniform float time; | |
| varying vec2 vUv; | |
| varying vec3 vPosition; | |
| varying vec3 vNormal; | |
| #define PHI 1.61803398874989484820459 | |
| #define PI 3.14159265359 | |
| #define GOLDEN_ANGLE 2.39996322972865332 | |
| #define E 2.71828182845904523536 | |
| float rand(vec2 n) { | |
| return fract(sin(dot(n, vec2(12.9898, 4.1414))) * 43758.5453); | |
| } | |
| float noise(vec2 p) { | |
| vec2 ip = floor(p); | |
| vec2 u = fract(p); | |
| u = u*u*(3.0-2.0*u); | |
| float res = mix( | |
| mix(rand(ip), rand(ip+vec2(1.0,0.0)), u.x), | |
| mix(rand(ip+vec2(0.0,1.0)), rand(ip+vec2(1.0,1.0)), u.x), u.y); | |
| return res*res; | |
| } | |
| float voronoi(vec2 x) { | |
| vec2 p = floor(x); | |
| vec2 f = fract(x); | |
| float res = 8.0; | |
| for(int j=-1; j<=1; j++) | |
| for(int i=-1; i<=1; i++) { | |
| vec2 b = vec2(i, j); | |
| vec2 r = b - f + rand(p + b); | |
| float d = dot(r, r); | |
| res = min(res, d); | |
| } | |
| return sqrt(res); | |
| } | |
| float fibonacci(vec2 p, float t) { | |
| float angle = atan(p.y, p.x); | |
| float radius = length(p); | |
| float spiral = log(radius) / PHI - angle - t * 0.2; | |
| float wave = sin(spiral * 8.0 + t * GOLDEN_ANGLE) * | |
| cos(spiral * 5.0 + t * PHI) * | |
| sin(spiral * 3.0 + t * E); | |
| float voronoi_val = voronoi(p * 2.0 + t * 0.25); | |
| float noise_val = noise(p * 3.0 + t * 0.5 + vec2(sin(t), cos(t))); | |
| return smoothstep(0.0, 0.2, abs(wave)) * | |
| (1.0 + noise_val * 0.8) * | |
| (1.0 + voronoi_val * 0.5); | |
| } | |
| vec3 palette(float t) { | |
| vec3 a = vec3(0.8, 0.5, 0.4); | |
| vec3 b = vec3(0.2, 0.4, 0.2); | |
| vec3 c = vec3(2.0, 1.0, 1.0); | |
| vec3 d = vec3(0.00, 0.33, 0.67); | |
| return a + b * cos(2.0 * PI * (c * t + d + vec3(time * 0.1))); | |
| } | |
| float fbm(vec2 p) { | |
| float value = 0.0; | |
| float amplitude = 0.5; | |
| float frequency = 1.0; | |
| mat2 rotation = mat2(cos(0.5), sin(0.5), -sin(0.5), cos(0.5)); | |
| for (int i = 0; i < 8; i++) { | |
| value += amplitude * noise(p * frequency); | |
| p = rotation * p * 2.0; | |
| frequency *= 2.0; | |
| amplitude *= 0.5; | |
| } | |
| return value; | |
| } | |
| void main() { | |
| vec2 uv = (vUv - 0.5) * 2.0; | |
| float aspect = 1.0; | |
| uv.x *= aspect; | |
| float zoom = 3.0 + sin(time * PHI) * 0.5 + cos(time * E) * 0.3; | |
| uv *= zoom; | |
| float rotation = time * 0.2 + sin(time * PHI) * 0.2 + cos(time * E) * 0.1; | |
| mat2 rot = mat2(cos(rotation), -sin(rotation), sin(rotation), cos(rotation)); | |
| uv = rot * uv; | |
| float fib = fibonacci(uv, time); | |
| vec2 movement = vec2( | |
| sin(time * PHI + uv.y) * 0.3 + cos(time * E + uv.x) * 0.2, | |
| cos(time * GOLDEN_ANGLE + uv.x) * 0.3 + sin(time * PHI + uv.y) * 0.2 | |
| ); | |
| uv += movement; | |
| float dist = length(uv); | |
| float fbm_val = fbm(uv * 1.5 + time * 0.1); | |
| vec3 color1 = palette(dist * 0.3 + time * 0.2); | |
| vec3 color2 = palette(fbm_val + time * PHI * 0.1); | |
| vec3 color3 = palette(voronoi(uv * 2.0) + time * E * 0.1); | |
| vec3 color = mix(color1, color2, fbm_val); | |
| color = mix(color, color3, voronoi(uv + time * 0.1)); | |
| color *= 1.0 - fib; | |
| float glow = exp(-dist * (1.0 + sin(time * GOLDEN_ANGLE) * 0.5)); | |
| vec3 glowColor = palette(time * PHI * 0.1) * 1.2; | |
| color += glowColor * glow; | |
| float vignette = smoothstep(1.5, 0.4, length(vUv - 0.5)); | |
| color *= vignette; | |
| color = pow(color, vec3(0.8)); | |
| float luminance = dot(color, vec3(0.299, 0.587, 0.114)); | |
| color = mix(vec3(luminance), color, 1.5); | |
| color *= 1.4 + sin(time * PHI) * 0.2 + cos(time * E) * 0.1; | |
| color = mix(color, color * color, 0.4); | |
| color += pow(max(color, 0.0), vec3(4.0)) * 0.5; | |
| gl_FragColor = vec4(color, 1.0); | |
| }`; | |
| function init() { | |
| scene = new THREE.Scene(); | |
| camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0.1, 10); | |
| camera.position.z = 1; | |
| renderer = new THREE.WebGLRenderer({ | |
| canvas: document.querySelector("#canvas"), | |
| antialias: true, | |
| powerPreference: "high-performance", | |
| precision: "highp" | |
| }); | |
| const pixelRatio = Math.min(window.devicePixelRatio, 2); | |
| renderer.setPixelRatio(pixelRatio); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| const geometry = new THREE.PlaneGeometry(2, 2); | |
| const material = new THREE.ShaderMaterial({ | |
| vertexShader, | |
| fragmentShader, | |
| uniforms: { | |
| time: { | |
| value: 0 | |
| } | |
| } | |
| }); | |
| const mesh = new THREE.Mesh(geometry, material); | |
| scene.add(mesh); | |
| renderer.outputEncoding = THREE.sRGBEncoding; | |
| renderer.toneMapping = THREE.ACESFilmicToneMapping; | |
| renderer.toneMappingExposure = 1.2; | |
| } | |
| let lastTime = performance.now(); | |
| const targetFrameRate = 60; | |
| const frameInterval = 1000 / targetFrameRate; | |
| function animate() { | |
| requestAnimationFrame(animate); | |
| const currentTime = performance.now(); | |
| const deltaTime = currentTime - lastTime; | |
| if (deltaTime >= frameInterval) { | |
| time += 0.016; | |
| const material = scene.children[0].material; | |
| material.uniforms.time.value = time; | |
| renderer.render(scene, camera); | |
| lastTime = currentTime - (deltaTime % frameInterval); | |
| } | |
| } | |
| function onWindowResize() { | |
| const pixelRatio = Math.min(window.devicePixelRatio, 2); | |
| renderer.setPixelRatio(pixelRatio); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| } | |
| window.addEventListener("resize", onWindowResize, false); | |
| init(); | |
| animate(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| body { | |
| margin: 0; | |
| overflow: hidden; | |
| background: #000; | |
| font-family: "Press Start 2P", cursive; | |
| } | |
| canvas { | |
| width: 100vw; | |
| height: 100vh; | |
| display: block; | |
| } | |
| .button-3d { | |
| position: fixed; | |
| bottom: 20px; | |
| left: 20px; | |
| padding: 15px 25px; | |
| background: linear-gradient(45deg, #ff6b6b, #ff8e8e); | |
| color: white; | |
| text-decoration: none; | |
| border: none; | |
| transform: perspective(500px) rotateX(10deg); | |
| transform-style: preserve-3d; | |
| transition: all 0.3s ease; | |
| text-shadow: 0 2px 2px rgba(0, 0, 0, 0.2); | |
| box-shadow: 0 6px 0 #cc5757, 0 8px 10px rgba(0, 0, 0, 0.3); | |
| z-index: 1000; | |
| font-size: 12px; | |
| letter-spacing: 1px; | |
| text-transform: uppercase; | |
| cursor: pointer; | |
| } | |
| .button-3d:hover { | |
| transform: perspective(500px) rotateX(15deg) translateY(-2px); | |
| box-shadow: 0 8px 0 #cc5757, 0 12px 15px rgba(0, 0, 0, 0.3); | |
| } | |
| .button-3d:active { | |
| transform: perspective(500px) rotateX(10deg) translateY(2px); | |
| box-shadow: 0 4px 0 #cc5757, 0 5px 8px rgba(0, 0, 0, 0.3); | |
| } | |
| .credits { | |
| position: fixed; | |
| bottom: 20px; | |
| right: 20px; | |
| color: #ff8e8e; | |
| font-size: 14px; | |
| z-index: 1000; | |
| opacity: 0.8; | |
| animation: pulse 2s ease-in-out infinite alternate; | |
| } | |
| @keyframes pulse { | |
| from { | |
| opacity: 0.8; | |
| transform: scale(1); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: scale(1.05); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment