fun!
Log in to post a comment.
#version 300 es
precision highp float;
uniform float iTime;
uniform vec2 iResolution;
out vec4 fragColor;
// Better hash
float hash(vec2 p) {
p = fract(p * vec2(123.34, 456.21));
p += dot(p, p + 45.32);
return fract(p.x * p.y);
}
// Basic value noise with smoother interpolation
float valueNoise(vec2 p) {
vec2 i = floor(p);
vec2 f = fract(p);
float a = hash(i + vec2(0.0, 0.0));
float b = hash(i + vec2(1.0, 0.0));
float c = hash(i + vec2(0.0, 1.0));
float d = hash(i + vec2(1.0, 1.0));
vec2 u = f * f * (3.0 - 2.0 * f); // smootherstep
return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);
}
// fbm with zoomed-in detail
float fbm(vec2 p) {
float total = 0.0;
float amplitude = 0.6;
float frequency = 1.0;
for (int i = 0; i < 5; i++) {
total += valueNoise(p * frequency) * amplitude;
frequency *= 2.2;
amplitude *= 0.5;
}
return total;
}
void main() {
vec2 uv = gl_FragCoord.xy / iResolution.xy;
uv = uv * 2.0 - 1.0;
uv.x *= iResolution.x / iResolution.y;
// Tilted surface
mat2 skew = mat2(1.0, -0.4, 0.0, 1.0);
vec2 viewUV = skew * uv;
// Scrolling
vec2 pan = vec2(iTime * 0.4, iTime * 0.2);
vec2 worldUV = viewUV * 4.0 + pan; // 🔍 Zoomed in from 8.0 to 4.0
// Bump height
float h = fbm(worldUV);
// Normal from height map
float eps = 0.005;
float hx = fbm(worldUV + vec2(eps, 0.0));
float hy = fbm(worldUV + vec2(0.0, eps));
vec3 n = normalize(vec3(h - hx, h - hy, eps));
// Light and view
float time = iTime * 0.8;
vec3 lightDir = normalize(vec3(sin(time * 1.7), cos(time * 2.1), 1.2));
vec3 viewDir = vec3(0.0, 0.0, 1.0);
float diff = max(dot(n, lightDir), 0.0);
float spec = pow(max(dot(n, normalize(lightDir + viewDir)), 0.0), 60.0);
// Color from height
vec3 baseColor = mix(vec3(0.1, 0.1, 0.2), vec3(0.9, 0.85, 0.7), h);
vec3 color = baseColor * diff + vec3(1.0) * spec * 0.6;
fragColor = vec4(color, 1.0);
}