Project_2026-02-12_21-16-32

GLSL shader by merrypranxter · created 2026-02-13 · 10s loop · 2 passes

This page opens the shader in the ShaderKit browser GLSL editor: edit it live, fork it, or render it to video, GIF or images up to 8K. Also available as a full-screen view and an embeddable player.

Shader source (GLSL)

Common

#define pi acos(-1.)
#define deg pi/180.  //1 degree
#define time iTime*2.*pi/10. //sin(time) loops 10 seconds
#define R iResolution.xy //shorthand
#define ar R.x/R.y //aspect ratio
#define M iMouse //shorthand
#define xm (M.xy/R) //normalized mouse
#define nm ((xm.xy-0.5)*vec2(ar,1.)+0.5) //aspect ratio correction
vec3 cs = vec3(1.,2.,3.);
mat2 r2d(float a) {
    return mat2(cos(a),sin(a),-sin(a),cos(a));
}

Buffer A (iChannel0)

// --- THE HYPER-LUMINOUS AGATE FLOW ---
// "ACTIVE MINERAL" / ULTRA-TEXTURAL / HIGH-DEF
// LOOKS LIKE A POLISHED SLICE OF ALIEN ROCK

#define OCTAVES 6           // Detail Level (High but safe)
#define WARP_STRENGTH 2.0   // How twisted the bands get
#define SCALE 2.5           // Zoom level
#define SPEED iTime * 0.05  // Geological Time Scale

// 1. THE MINERAL PALETTE (Deep Earth & New Age Glam)
vec3 agate_palette(float t) {
    vec3 a = vec3(0.5, 0.5, 0.5);
    vec3 b = vec3(0.5, 0.5, 0.5);
    vec3 c = vec3(1.0, 1.0, 1.0);
    vec3 d = vec3(0.0, 0.33, 0.67); // Rainbow Phase
    
    vec3 col = a + b * cos(6.28318 * (c * t + d));
    
    // Remap to Mineral Tones:
    // Deep Purple Shadows -> Teal Mids -> Creamy Quartz Highs
    col = mix(vec3(0.1, 0.0, 0.2), vec3(0.0, 0.6, 0.6), smoothstep(0.0, 0.4, col.g));
    col = mix(col, vec3(0.95, 0.9, 0.8), smoothstep(0.6, 1.0, col.r));
    
    return col;
}

// 2. NOISE FUNCTIONS (The "Grain")
float random(vec2 st) {
    return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.5453123);
}

float noise(vec2 st) {
    vec2 i = floor(st);
    vec2 f = fract(st);
    float a = random(i);
    float b = random(i + vec2(1.0, 0.0));
    float c = random(i + vec2(0.0, 1.0));
    float d = random(i + vec2(1.0, 1.0));
    vec2 u = f * f * (3.0 - 2.0 * f);
    return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
}

float fbm(vec2 st) {
    float value = 0.0;
    float amplitude = 0.5;
    float frequency = 0.0;
    for (int i = 0; i < OCTAVES; i++) {
        value += amplitude * noise(st);
        st *= 2.0;
        amplitude *= 0.5;
    }
    return value;
}

// 3. THE AGATE PATTERN (Domain Warping)
float get_agate(vec2 p, out float warping) {
    // WARP 1: Big Shifts
    vec2 q = vec2(
        fbm(p + vec2(0.0, 0.0) + SPEED),
        fbm(p + vec2(5.2, 1.3) + SPEED)
    );
    
    // WARP 2: Detail Shifts (The "Bands")
    vec2 r = vec2(
        fbm(p + 4.0 * q + vec2(1.7, 9.2) + 0.15 * iTime),
        fbm(p + 4.0 * q + vec2(8.3, 2.8) + 0.126 * iTime)
    );
    
    warping = length(r); // Save this for coloring
    
    return fbm(p + WARP_STRENGTH * r);
}

void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
    vec2 uv = (fragCoord * 2.0 - iResolution.xy) / iResolution.y;
    vec2 uv0 = uv;
    uv *= SCALE;

    // A. GENERATE THE STONE
    float warp_val;
    float pattern = get_agate(uv, warp_val);
    
    // B. CALCULATE HEIGHT & NORMALS (For "Ultra-Texture")
    // We create a "Normal Map" on the fly from the pattern
    float e = 0.002;
    float h = pattern;
    float h_x = get_agate(uv + vec2(e, 0.0), warp_val);
    float h_y = get_agate(uv + vec2(0.0, e), warp_val);
    
    // "Normal" vector points perpendicular to the slope
    vec3 normal = normalize(vec3(h - h_x, h - h_y, e * 10.0));
    
    // C. LIGHTING (The "Hyper-Real" polish)
    vec3 light_dir = normalize(vec3(1.0, 1.0, 1.5));
    
    // Diffuse: Basic shape definition
    float diff = max(dot(normal, light_dir), 0.0);
    
    // Specular: The "Wet Stone" look
    // High power (64.0) makes it look polished
    vec3 view_dir = normalize(vec3(0.0, 0.0, 1.0));
    vec3 half_vec = normalize(light_dir + view_dir);
    float spec = pow(max(dot(normal, half_vec), 0.0), 64.0);
    
    // D. COLORING THE BANDS
    // We map the noise pattern to concentric rings using sine
    float rings = sin(pattern * 20.0 + warp_val * 5.0);
    rings = smoothstep(-0.8, 0.8, rings); // Sharpen the bands
    
    // Mix the palette based on the warped noise
    vec3 col = agate_palette(pattern + warp_val * 0.2);
    
    // Darken the "Depths" (The rings)
    col *= 0.5 + 0.5 * rings;
    
    // E. SUBSURFACE GLOW
    // Add "Inner Light" to the translucent parts
    float inner_glow = smoothstep(0.4, 0.6, pattern);
    col += vec3(0.9, 0.7, 0.5) * inner_glow * 0.3; // Amber light
    
    // F. COMPOSITE
    col *= (diff * 0.8 + 0.3); // Ambient + Diffuse
    col += vec3(1.0) * spec * 0.8; // Add the wet shine
    
    // G. MICRO-DETAIL (Sand/Crystal Grain)
    float grain = fract(sin(dot(uv * 50.0, vec2(12.98, 78.23))) * 43758.54);
    col += (grain - 0.5) * 0.05;

    // H. POST-PROCESS
    col = pow(col, vec3(0.4545)); // Gamma
    col *= 1.2 - length(uv0) * 0.5; // Vignette

    fragColor = vec4(clamp(col, 0.0, 1.0), 1.0);
}

Image

Not used

More shaders by merrypranxter

Browse all public shaders · All shaders by merrypranxter · ShaderKit home

Vibe Mode BETA
💰 ~0 credits
Uniforms
FPS: 0
Time: 0
Resolution: 0 x 0

Account

FPS: -- Time: -- --×-- 1x