Chromatic Plexus
GLSL shader by merrypranxter · created 2026-02-14 · 10s loop · 2 passes
Volumetric fiber web sphere with 8 independent thread families — latitudinal, longitudinal, diagonal, and spiral — each lit by a different palette. Spiky surface morphs as it rotates through three axes simultaneously.
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)
// ============================================================
// CHROMATIC PLEXUS v1.0
// Volumetric fiber web sphere + Lisa Frank palette
// No reserved words, compiler safe
// ============================================================
const float PI = 3.14159265359;
const float TAU = 6.28318530718;
const float speed = 0.18;
const float fiberSharp = 90.0;
const float fiberCount = 16.0;
const float brightness = 1.9;
const float spikeAmt = 0.18;
vec3 lfPalette(float t) {
vec3 a = vec3(0.5, 0.3, 0.6);
vec3 b = vec3(0.5, 0.5, 0.5);
vec3 c = vec3(1.0, 1.3, 0.9);
vec3 d = vec3(0.0, 0.25, 0.6);
return a + b * cos(TAU * (c * t + d));
}
vec3 neonPalette(float t) {
vec3 a = vec3(0.4, 0.2, 0.5);
vec3 b = vec3(0.5, 0.5, 0.4);
vec3 c = vec3(2.1, 1.5, 0.8);
vec3 d = vec3(0.1, 0.4, 0.9);
return a + b * cos(TAU * (c * t + d));
}
vec3 hotPalette(float t) {
vec3 a = vec3(0.6, 0.4, 0.3);
vec3 b = vec3(0.4, 0.5, 0.5);
vec3 c = vec3(0.5, 1.0, 2.0);
vec3 d = vec3(0.8, 0.2, 0.5);
return a + b * cos(TAU * (c * t + d));
}
mat3 rotX(float a) {
float ca = cos(a);
float sa = sin(a);
return mat3(1.0, 0.0, 0.0,
0.0, ca, -sa,
0.0, sa, ca);
}
mat3 rotY(float a) {
float ca = cos(a);
float sa = sin(a);
return mat3( ca, 0.0, sa,
0.0, 1.0, 0.0,
-sa, 0.0, ca);
}
mat3 rotZ(float a) {
float ca = cos(a);
float sa = sin(a);
return mat3( ca, -sa, 0.0,
sa, ca, 0.0,
0.0, 0.0, 1.0);
}
// ---- Individual fiber families ----
// Each returns glow intensity for one family of great-circle threads
float fiberLat(vec3 p, float t) {
float f = sin(p.y * fiberCount + t * 0.5);
return exp(-f * f * fiberSharp);
}
float fiberLon(vec3 p, float t) {
float ang = atan(p.z, p.x);
float f = sin(ang * fiberCount * 0.5 + t * 0.3);
return exp(-f * f * fiberSharp);
}
float fiberDiag1(vec3 p, float t) {
vec3 pr = rotX(PI * 0.25) * p;
float f = sin(pr.y * fiberCount * 0.8 + pr.x * fiberCount * 0.3 - t * 0.4);
return exp(-f * f * fiberSharp);
}
float fiberDiag2(vec3 p, float t) {
vec3 pr = rotZ(PI * 0.33) * p;
float f = sin(pr.y * fiberCount * 0.7 - pr.z * fiberCount * 0.4 + t * 0.2);
return exp(-f * f * fiberSharp);
}
float fiberSpiral(vec3 p, float t) {
float ang = atan(p.z, p.x);
float spiral = sin(p.y * fiberCount * 0.6 + ang * 4.0 - t * 0.6);
return exp(-spiral * spiral * fiberSharp * 0.8);
}
float fiberDiag3(vec3 p, float t) {
vec3 pr = rotX(PI * 0.5) * rotY(PI * 0.25) * p;
float ang = atan(pr.z, pr.x);
float f = sin(ang * fiberCount * 0.4 + pr.y * fiberCount * 0.5 + t * 0.35);
return exp(-f * f * fiberSharp);
}
float fiberDiag4(vec3 p, float t) {
vec3 pr = rotY(PI * 0.5) * rotZ(PI * 0.2) * p;
float f = sin(pr.x * fiberCount * 0.9 + pr.z * fiberCount * 0.2 - t * 0.25);
return exp(-f * f * fiberSharp);
}
float fiberSpiral2(vec3 p, float t) {
vec3 pr = rotY(PI * 0.5) * p;
float ang = atan(pr.z, pr.x);
float f = sin(pr.y * fiberCount * 0.5 + ang * 6.0 + t * 0.4);
return exp(-f * f * fiberSharp * 0.6);
}
// ---- Sphere surface spikes (displacement) ----
float spikeField(vec3 pn, float t) {
float s1 = sin(pn.x * 8.0 + t * 0.7) * sin(pn.y * 7.0 - t * 0.5) * sin(pn.z * 9.0 + t * 0.3);
float s2 = sin(pn.x * 13.0 - t * 0.4) * sin(pn.z * 11.0 + t * 0.6);
return max(0.0, s1 * 0.6 + s2 * 0.4);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;
float t = iTime * speed;
vec3 ro = vec3(0.0, 0.0, -3.2);
vec3 rd = normalize(vec3(uv, 1.4));
// Sphere-ray intersection
float sphereR = 1.15;
float b = dot(ro, rd);
float c = dot(ro, ro) - sphereR * sphereR * 1.6;
float disc = b * b - c;
vec3 col = vec3(0.01, 0.005, 0.02);
if(disc > 0.0) {
float sqD = sqrt(disc);
float tNear = max(-b - sqD, 0.0);
float tFar = -b + sqD;
if(tFar > 0.0) {
float tRange = tFar - tNear;
float stepSz = tRange / 80.0;
// Slow rotation
mat3 rot = rotY(t * 0.35) * rotX(t * 0.22) * rotZ(t * 0.13);
float totalW = 0.0;
vec3 colAcc = vec3(0.0);
for(int i = 0; i < 80; i++) {
float fi = float(i);
float td = tNear + fi * stepSz;
vec3 p = ro + rd * td;
vec3 pr = rot * p;
float plen = length(pr);
vec3 pn = pr / max(plen, 0.0001);
// Spiky shell radius
float spike = spikeField(pn, t);
float shellR = sphereR * (1.0 + spike * spikeAmt);
// Soft shell weight — concentrated near surface
float distToShell = abs(plen - shellR);
float shellW = exp(-distToShell * distToShell * 18.0);
// Also allow interior web
float interiorW = clamp(1.0 - plen / sphereR, 0.0, 1.0);
interiorW = interiorW * interiorW * 0.4;
float posW = shellW + interiorW;
// All fiber families
float f1 = fiberLat(pn, t);
float f2 = fiberLon(pn, t);
float f3 = fiberDiag1(pn, t);
float f4 = fiberDiag2(pn, t);
float f5 = fiberSpiral(pn, t);
float f6 = fiberDiag3(pn, t);
float f7 = fiberDiag4(pn, t);
float f8 = fiberSpiral2(pn, t);
// Color each family differently
float ang = atan(pn.z, pn.x);
float posPhase = pn.y * 0.5 + ang / TAU;
vec3 c1 = lfPalette(posPhase + 0.0) * f1;
vec3 c2 = neonPalette(posPhase + 0.15) * f2;
vec3 c3 = lfPalette(posPhase + 0.3) * f3;
vec3 c4 = hotPalette(posPhase + 0.45) * f4;
vec3 c5 = neonPalette(posPhase + 0.6) * f5;
vec3 c6 = lfPalette(posPhase + 0.75) * f6;
vec3 c7 = hotPalette(posPhase + 0.9) * f7;
vec3 c8 = neonPalette(posPhase + 1.05) * f8;
float totalFiber = f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8;
vec3 fiberCol = c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8;
float contrib = totalFiber * posW * stepSz;
colAcc += fiberCol * posW * stepSz;
totalW += contrib;
}
float alpha = clamp(totalW * 0.25, 0.0, 1.0);
vec3 fibCol = colAcc / max(totalW, 0.0001);
col = mix(col, fibCol, alpha);
col += fibCol * alpha * alpha * 1.5;
}
}
// Outer halo
float haloDist = length(uv);
float halo = exp(-haloDist * 3.0) * 0.12;
col += lfPalette(t * 0.08) * halo;
// Vignette
col *= 1.0 - dot(uv, uv) * 0.35;
col = pow(clamp(col * brightness, 0.0, 1.0), vec3(0.8));
col *= col * 1.4;
fragColor = vec4(col, 1.0);
}
Image
Not used
More shaders by merrypranxter
- PRISMACORE_003 — Retina Banquet
- PRISMACORE_002 — After Work Sky
- PRISMACORE_001 — Liquid Crystal Fever Dream
- Hopf Vibratiok in pink
- Void Geode
- Project_2026-02-14_04-53-13
- Signal Death
- Deep fried math
- Candy Interference
- Project_2026-02-12_21-16-32
- Project_2026-02-12_17-00-28
- Project_2026-02-12_16-17-50
Browse all public shaders · All shaders by merrypranxter · ShaderKit home
Unread comments
×Projects with new comments. Click to open and read.