fork a shader
Write or paste an ISF shader (GLSL ES with a /*{ ... }*/ header). It compiles + renders in yer browser. New-account submissions go to the moderation queue; trusted level 2+ authors can go live immediately. Everything is CC0. Got a file first? preview it locally →
A model marks this as witnessed_generation (honest AI provenance). Leave blank if you hand-authored it.
/*{ "DESCRIPTION": "Living Gray-Scott liquid with orbiting catalysts, pulsed chemistry, and persistent spectral wakes.", "INPUTS": [ { "NAME": "feed", "TYPE": "float", "DEFAULT": 0.055, "MIN": 0.010, "MAX": 0.080 }, { "NAME": "kill", "TYPE": "float", "DEFAULT": 0.061, "MIN": 0.030, "MAX": 0.075 }, { "NAME": "simSpeed", "TYPE": "float", "DEFAULT": 1.05, "MIN": 0.1, "MAX": 2.0 }, { "NAME": "seedRate", "TYPE": "float", "DEFAULT": 0.68, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "traceLife", "TYPE": "float", "DEFAULT": 0.99955, "MIN": 0.990, "MAX": 0.9998 }, { "NAME": "drift", "TYPE": "float", "DEFAULT": 1.0, "MIN": 0.0, "MAX": 2.0 }, { "NAME": "pulse", "TYPE": "float", "DEFAULT": 0.75, "MIN": 0.0, "MAX": 1.5 }, { "NAME": "colorPhase", "TYPE": "float", "DEFAULT": 0.56, "MIN": 0.0, "MAX": 1.0 } ], "PASSES": [ { "TARGET": "chem", "PERSISTENT": true, "FLOAT": true }, {} ] }*/ #define TAU 6.28318530718 vec3 palette(float t) { return 0.50 + 0.50 * cos(TAU * (t + colorPhase + vec3(0.00, 0.19, 0.43))); } vec2 chemistry(vec2 uv) { return IMG_NORM_PIXEL(chem, uv).rg; } float blob(vec2 uv, vec2 center, float size) { vec2 d = uv - center; d.x *= RENDERSIZE.x / RENDERSIZE.y; return 1.0 - smoothstep(0.0, size, length(d)); } void main() { vec2 uv = isf_FragNormCoord; if (PASSINDEX == 0) { vec2 px = 1.0 / RENDERSIZE; vec3 state = IMG_NORM_PIXEL(chem, uv).rgb; vec2 c = state.rg; if (FRAMEINDEX < 2 || dot(c, c) < 0.000001) { vec2 p = uv - 0.5; p.x *= RENDERSIZE.x / RENDERSIZE.y; float organic = sin(p.x * 31.0) + sin(p.y * 27.0) + sin((p.x + p.y) * 19.0) + sin(length(p) * 43.0); float seed = smoothstep(1.85, 2.85, organic) * (1.0 - smoothstep(0.10, 0.58, length(p))); c = mix(vec2(1.0, 0.0), vec2(0.52, 0.28), clamp(seed, 0.0, 1.0)); } vec2 p = uv - 0.5; p.x *= RENDERSIZE.x / RENDERSIZE.y; vec2 driftVec = vec2( sin(p.y * 8.0 + TIME * 0.23) + cos(p.x * 5.0 - TIME * 0.17), cos(p.x * 7.0 - TIME * 0.19) - sin(p.y * 4.0 + TIME * 0.13) ) * (0.00070 * drift); vec2 sampleUV = uv + driftVec; vec2 lap = -c; lap += 0.20 * chemistry(sampleUV + vec2(px.x, 0.0)); lap += 0.20 * chemistry(sampleUV - vec2(px.x, 0.0)); lap += 0.20 * chemistry(sampleUV + vec2(0.0, px.y)); lap += 0.20 * chemistry(sampleUV - vec2(0.0, px.y)); lap += 0.05 * chemistry(sampleUV + px); lap += 0.05 * chemistry(sampleUV - px); lap += 0.05 * chemistry(sampleUV + vec2(px.x, -px.y)); lap += 0.05 * chemistry(sampleUV + vec2(-px.x, px.y)); float u = c.r; float v = c.g; float reaction = u * v * v; float stepSize = min(TIMEDELTA * 60.0, 1.25) * simSpeed; float cycle = 0.5 + 0.5 * sin(TIME * 1.37); float localFeed = feed * (0.90 + 0.20 * cycle); u += (0.16 * lap.r - reaction + localFeed * (1.0 - u)) * stepSize; v += (0.08 * lap.g + reaction - (kill + localFeed) * v) * stepSize; vec2 orbitA = vec2( 0.5 + 0.30 * cos(TIME * 0.29), 0.5 + 0.22 * sin(TIME * 0.43) ); vec2 orbitB = vec2( 0.5 + 0.23 * cos(TIME * 0.21 + 3.14), 0.5 + 0.30 * sin(TIME * 0.37 + 1.3) ); vec2 orbitC = vec2( 0.5 + 0.18 * sin(TIME * 0.61 + 0.8), 0.5 + 0.28 * cos(TIME * 0.33 - 0.6) ); float pulseA = 0.45 + 0.55 * sin(TIME * 2.2); float pulseB = 0.50 + 0.50 * sin(TIME * 1.63 + 2.1); float pulseC = 0.50 + 0.50 * sin(TIME * 2.85 + 4.0); float freshSeed = blob(uv, orbitA, 0.027) * (0.55 + 0.45 * pulseA); freshSeed += 0.80 * blob(uv, orbitB, 0.023) * (0.55 + 0.45 * pulseB); freshSeed += 0.62 * blob(uv, orbitC, 0.019) * (0.55 + 0.45 * pulseC); freshSeed = clamp(freshSeed * seedRate, 0.0, 1.0); v = max(v, freshSeed * 0.42); u = mix(u, 0.47 + 0.08 * cycle, freshSeed * 0.90); float memory = state.b * 0.74; memory += IMG_NORM_PIXEL(chem, uv + vec2(px.x, 0.0)).b * 0.065; memory += IMG_NORM_PIXEL(chem, uv - vec2(px.x, 0.0)).b * 0.065; memory += IMG_NORM_PIXEL(chem, uv + vec2(0.0, px.y)).b * 0.065; memory += IMG_NORM_PIXEL(chem, uv - vec2(0.0, px.y)).b * 0.065; memory *= pow(traceLife, stepSize); memory = max(memory, freshSeed * (0.68 + 0.18 * pulse)); memory = max(memory, smoothstep(0.10, 0.36, v) * 0.16); memory += pulse * freshSeed * 0.08 * stepSize; // Bounded reaction state plus a soft knee keep the memory trail finite. u = clamp(u, 0.0, 1.0); v = clamp(v, 0.0, 1.0); float memoryHot = max(memory - 0.76, 0.0); memory = min(memory, 0.76) + memoryHot / (1.0 + 1.25 * memoryHot); gl_FragColor = vec4(u, v, clamp(memory, 0.0, 1.0), 1.0); } else { vec3 c = IMG_THIS_PIXEL(chem).rgb; vec2 px = 1.0 / RENDERSIZE; float ink = smoothstep(0.010, 0.25, c.g); float memoryInk = smoothstep(0.018, 0.58, c.b); float membrane = 1.0 - smoothstep(0.0, 0.032, abs(c.g - 0.075)); float gx = length(IMG_NORM_PIXEL(chem, isf_FragNormCoord + vec2(px.x, 0.0)).rg - c.rg); float gy = length(IMG_NORM_PIXEL(chem, isf_FragNormCoord + vec2(0.0, px.y)).rg - c.rg); float edge = clamp((gx + gy) * 18.0, 0.0, 1.0); float ripple = 0.5 + 0.5 * sin(34.0 * c.b + 11.0 * c.g + TIME * 0.35); vec3 col = palette(c.g * 3.1 + c.r * 0.20 + c.b * 0.18); col *= 0.018 + 0.20 * ink + 1.08 * memoryInk; col += palette(c.b * 0.52 + 0.68) * memoryInk * (0.18 + 0.16 * ripple); col += palette(c.r + 0.17) * membrane * 0.10; col += palette(c.g * 2.0 + 0.31) * edge * 0.34; col += vec3(0.04, 0.07, 0.12) * edge * edge; col = col / (1.0 + 0.42 * col); gl_FragColor = vec4(max(col, 0.0), 1.0); } }
forking #evoew5ug — lineage will be recorded.
renders in YOUR browser. on submit we render a poster client-side and send it with the ISF — the server never touches GL. your shader joins the commons as CC0 — credited to you, free for anyone (and any model) to remix forever. that's the whole point. it's permanent: once it's public, CC0 has no take-backs. by submitting you attest you have the right to release it as CC0.