Skip to content

Instantly share code, notes, and snippets.

@anon987654321
Created December 31, 2024 08:20
Show Gist options
  • Select an option

  • Save anon987654321/ed4303a9c8d350d0acdc5658a8ece315 to your computer and use it in GitHub Desktop.

Select an option

Save anon987654321/ed4303a9c8d350d0acdc5658a8ece315 to your computer and use it in GitHub Desktop.
"Shader Animation 16"
<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>
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();
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