From a900c5f750b5a876266a16c818f7bf62995ee062 Mon Sep 17 00:00:00 2001 From: dangrubbb Date: Sat, 24 Oct 2026 09:29:07 -0400 Subject: [PATCH] radiance: shaded coral body + deeper right rim, red mass weighted to lower latitudes, bigger flakes, crisper haloed glints and corona --- src/scripts/orb.js | 50 +++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/scripts/orb.js b/src/scripts/orb.js index 0c80ce5..7725771 100644 --- a/src/scripts/orb.js +++ b/src/scripts/orb.js @@ -104,7 +104,12 @@ float layerR(uint idx) { float density(vec3 dir, float t) { vec3 w = dir * 1.6 + vec3(0.0, t * 0.05, t * 0.035); float n = fbm(w + 1.6 * fbm(w * 0.8 + 3.1)); - return clamp(1.0 - abs(n - 0.48) * 4.2, 0.0, 1.0); + float ridge = 1.0 - abs(n - 0.48) * 4.2; + // plus broad swells, so red gathers in big masses and not only thin ribbons + float swell = fbm(dir * 0.9 + vec3(0.0, t * 0.03, 7.3)); + float d = clamp(max(ridge, (swell - 0.4) * 3.2), 0.0, 1.0); + // the red gathers toward the middle latitudes (the lower part of what the camera sees), thinning over the crown + return d * mix(0.6, 1.0, 1.0 - smoothstep(0.15, 0.85, dir.y)); } // where a particle is reborn: best of four candidates against the density field vec3 spawnDir(uint idx, float epoch, float t) { @@ -146,7 +151,7 @@ P corona(uint idx) { float n = fbm(vec3(cd * 4.2, t * 0.10)); float up = smoothstep(-0.75, 0.9, cd.y); float spike = pow(n, 1.6) * 1.6; - float reach = pow(o.r.x, 1.5) * (0.05 + 0.4 * spike) * (0.3 + 0.7 * up); + float reach = pow(o.r.x, 1.3) * (0.07 + 0.5 * spike) * (0.3 + 0.7 * up); reach *= 0.88 + 0.12 * sin(t * 0.7 + o.r.w * 20.0); reach += 0.012 * sin(t * 0.9 + o.r.z * 30.0); o.n = n; @@ -430,7 +435,7 @@ void main() { if (idx < uInner) { vec4 r = vec4(h01(idx * 8u), h01(idx * 8u + 1u), h01(idx * 8u + 2u), h01(idx * 8u + 3u)); - float spark = step(0.88, h01(idx * 8u + 6u)); + float spark = step(0.86, h01(idx * 8u + 6u)); float rt = layerR(idx); float lt = lifeT(idx, t); vec3 pos = s0.xyz; @@ -442,12 +447,12 @@ void main() { vp = bp.xy * persp; float n = density(normalize(pos + vec3(1e-5)), t); - vec3 warm = mix(vec3(0.94, 0.27, 0.20), vec3(1.0, 0.52, 0.32), r.w); - warm = mix(warm, vec3(1.0, 0.72, 0.42), smoothstep(0.1, 0.45, 1.0 - n) * 0.8); - col = vec4(mix(warm, vec3(1.0, 0.97, 0.84), spark), mix(0.95, 0.95, spark)); - size = mix(1.15 + r.y * 1.2 + n * 0.8, 2.0 + r.w * 2.0, spark); + vec3 warm = mix(vec3(0.88, 0.17, 0.15), vec3(1.0, 0.45, 0.28), r.w * r.w); + warm = mix(warm, vec3(1.0, 0.70, 0.40), smoothstep(0.25, 0.7, 1.0 - n) * 0.85); + col = vec4(mix(warm, vec3(1.0, 0.99, 0.92), spark), 0.95); + size = mix(1.5 + r.y * 1.5 + n * 1.3, 2.8 + r.w * 2.4, spark); float tw = 0.5 + 0.5 * sin(t * (1.2 + r.x * 2.5) + r.w * 40.0); - col.a *= mix(1.0, tw, spark); + col.a *= mix(1.0, mix(0.4, 1.0, tw), spark); vGlow = spark; // the far side reads dimmer through the glass, and so do particles hanging deep in the volume // (it also thins the crowd that edge-on particles would form along the limb) @@ -465,10 +470,13 @@ void main() { float stir = clamp(length(disp) * 1.6 + length(s1.xy) * 0.35, 0.0, 1.5); vp = p.xy + disp; float tw = 0.5 + 0.5 * sin(t * (1.0 + p.r.y * 3.0) + p.r.z * 60.0); - col = vec4(1.0, 0.97, 0.86, (0.3 + 0.7 * p.fade) * (0.35 + 0.65 * smoothstep(0.2, 0.75, p.n))); - col.a *= mix(0.5, 1.0, tw); - size = 1.0 + p.r.y * p.r.y * 2.6 * (0.3 + p.fade); - vGlow = 0.5; + col = vec4(1.0, 0.98, 0.88, (0.45 + 0.55 * p.fade) * (0.5 + 0.5 * smoothstep(0.2, 0.75, p.n))); + col.a *= mix(0.55, 1.0, tw); + // a minority of sparks are bright, haloed points; the rest stay faint dust + float lead = step(0.7, p.r.x); + col.a *= mix(0.7, 1.0, lead); + size = (1.0 + p.r.y * p.r.y * 2.8 * (0.3 + p.fade)) * mix(0.9, 1.5, lead); + vGlow = mix(0.4, 1.0, lead); // sparks that get knocked off the limb flare, then fade out while they are away from home float away = smoothstep(0.03, 0.5, length(disp)); col.a *= 1.0 - 0.8 * away; @@ -491,7 +499,7 @@ void main() { vec2 c = gl_PointCoord - 0.5; float r = length(c); float core = smoothstep(0.5, 0.18, r); - float halo = vGlow * smoothstep(0.5, 0.0, r) * 0.35; + float halo = vGlow * smoothstep(0.5, 0.0, r) * 0.55; float a = vColor.a * clamp(core + halo, 0.0, 1.0); if (a < 0.01) discard; o = vec4(vColor.rgb * a, a); @@ -575,17 +583,19 @@ void main() { float z = sqrt(max(0.0, 1.0 - r * r)); vec3 n = vec3(d.x, -d.y, z); - // glassy body: lighter top-left, deeper orange bottom-right - vec3 top = vec3(1.0, 0.77, 0.56); - vec3 bot = vec3(1.0, 0.56, 0.42); - float lit = clamp(0.5 + 0.5 * dot(normalize(n), normalize(vec3(-0.45, 0.6, 0.65))), 0.0, 1.0); + // shaded body: peach at the top-left deepening to saturated coral toward the bottom and right + vec3 top = vec3(1.0, 0.80, 0.58); + vec3 bot = vec3(1.0, 0.45, 0.33); + float lit = clamp(0.5 + 0.5 * dot(normalize(n), normalize(vec3(-0.5, 0.55, 0.65))), 0.0, 1.0); + lit = pow(lit, 1.6); vec3 body = mix(bot, top, lit); + body = mix(body, vec3(1.0, 0.33, 0.28), smoothstep(-0.3, 0.25, d.y) * 0.45); // the lower visible band runs red - // fresnel rim, pale pink-white + // fresnel rim: pale on the left, deeper pink on the right float fres = pow(1.0 - z, 1.8); - vec3 rim = vec3(1.0, 0.85, 0.83); + vec3 rim = mix(vec3(1.0, 0.86, 0.84), vec3(1.0, 0.52, 0.55), smoothstep(-0.2, 0.8, d.x)); vec3 col = mix(body, rim, clamp(fres * 1.15, 0.0, 1.0)); - float a = mix(0.58, 0.97, fres); + float a = mix(0.72, 0.97, fres); // crisp bright edge line float ring = smoothstep(0.955, 0.985, r) * (1.0 - smoothstep(0.985, 1.004, r));