vestige/docs/launch/living-brain-hero-spec.json
Sam Valladares cfe8d03d36 feat(landing): full-viewport GPU node-engine hero + waitlist + dashboard auth removal
The /launch landing page (bleeding-edge waitlist hero):
- Full-viewport WebGL node engine (src/lib/hero/nodeEngine.ts): 40k GPU particles
  on a two-FBO GPUComputationRenderer running an 18s looping cinematic — particles
  stream in from the screen edges, slam together and EXPLODE at center, reform into
  a brain / graph constellation / neural lattice, dissolve back out, loop. Glowing
  additive particles + UnrealBloom, fills the whole screen edge to edge.
- Key GPGPU fix: custom DataTexture shape targets read black in GPUComputationRenderer
  (three.js #15882), so shape targets are computed PROCEDURALLY in-shader from the
  per-particle seed. Position integrates raw per-frame velocity (Codrops pattern),
  texel-center reference attribute.
- AmbientField (god-ray glow + parallax starfield), phantomBrain (deterministic
  seed-from-identity memory graph), LandingHero/neuralFlow (WebGPU Cinema-storm
  reuse + WebGL fallback, kept as alternates). Manifesto copy, seed input, email
  capture. No em-dashes. SSR off + prerender for the WebGL route.

Waitlist backend (Supabase, owned data):
- supabase/migrations/0001_waitlist.sql (RLS-locked table, dedup), Edge Function
  waitlist-join (CORS, validation, honeypot, dedup, Resend confirmation), setup doc.

Dashboard auth removed (reverts the launch-polish auth wall that 401'd the dashboard
against itself): mod.rs/state.rs/websocket.rs back to no-token, api.ts/websocket.ts/
+layout.svelte stripped of the token client. Pending-review UX + Memory PR gating kept.

Research/spec docs under docs/launch/. Frontend typechecks 0/0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 22:54:51 -05:00

36 lines
No EOL
14 KiB
JSON

{
"concept": "A 65,536-particle GPU field that inhales the word \"VESTIGE\" out of chaos, exhales it into a dense, breathing, iridescent brain whose bright tracts trace real memory-graph pathways, then lets the cursor part the cortex like liquid and watch it heal \u2014 a living second brain that is a function of Sam's data, not a copyable starfield.",
"entranceAnimation": "Timeline driven by one CPU uniform uFormProgress (GSAP easeOutExpo, 0->1 over 0.0-1.2s) plus uDissolve and a word/brain target swap. Beat 0 (0-0.9s): the same 65k points are seeded onto a canvas-rendered \"VESTIGE\" wordmask (pick random pixels where alpha>0.5 -> targetA texture); a critically-damped spring (k ramps 0->14*uFormProgress, damping 0.86 so it overshoots ~3% and settles) snaps the chaos cloud into legible, screenshot-able text while low-amp curl keeps it alive. Beat 1 (0.9-1.4s): uDissolve 0->1 disintegrates the letters left-to-right via a Perlin-remapped per-glyph mask (step(uDissolve, remap)) with wind+rise+curl drift \u2014 the IDENTICAL particles are conserved, never respawned, so the dust that was \"V\" becomes specific neurons. Beat 2 (1.4-3.0s): the freed particles re-target the brain point cloud (targetB = baked memory-graph projection) through the same spring; a per-particle simplex-of-target-position delay (delay = (snoise(targetPos*scale)*0.5+0.5)*0.6) makes formation SWEEP across the cortex like a propagating thought instead of popping as a blob, with a size-pop (sin(p*PI)*1.8) and an emissive dissolve-frontier band (uEdgeBoost>1.0) that UnrealBloom catches as a moving rim of neural ignition. At t=3s the brain is formed, breathing, and the first idle synapse fires.",
"brainCoreSpec": "Confine an analytic two-lobe brain SDF and make flow run TANGENT to it (curl of an SDF-gradient-modulated noise potential is divergence-free, so streamlines parallel the shell \u2014 particles glide along the cortex, never pierce it).\n\nfloat sdEllipsoid(vec3 p, vec3 r){ float k0=length(p/r); float k1=length(p/(r*r)); return k0*(k0-1.0)/k1; }\nfloat brainSDF(vec3 p){\n float L = sdEllipsoid(p-vec3(-0.32,0.0,0.0), vec3(0.85,0.95,1.15));\n float R = sdEllipsoid(p-vec3( 0.32,0.0,0.0), vec3(0.85,0.95,1.15));\n float d = min(L,R);\n d += 0.06*sin(8.0*p.x)*sin(7.0*p.y)*sin(6.0*p.z); // sulci/gyri wrinkles\n return d;\n}\nvec3 sdfNormal(vec3 p){ const vec2 e=vec2(1.0,-1.0)*0.004;\n return normalize(e.xyy*brainSDF(p+e.xyy)+e.yyx*brainSDF(p+e.yyx)+e.yxy*brainSDF(p+e.yxy)+e.xxx*brainSDF(p+e.xxx)); }\nvec3 potential(vec3 p){ return sdfNormal(p)*snoise(p*1.6 + uTime*0.15); } // tangential when curl'd\nvec3 curlNoise(vec3 p){ const float e=0.012; vec3 dx=vec3(e,0,0),dy=vec3(0,e,0),dz=vec3(0,0,e);\n float x=potential(p+dy).z-potential(p-dy).z-(potential(p+dz).y-potential(p-dz).y);\n float y=potential(p+dz).x-potential(p-dz).x-(potential(p+dx).z-potential(p-dx).z);\n float z=potential(p+dx).y-potential(p-dx).y-(potential(p+dy).x-potential(p-dy).x);\n return vec3(x,y,z)/(2.0*e); }\n\nDENSITY (the anti-starfield): each particle carries life in the FBO .w; decrement, and on death reseed onto the shell with center-weighted radius rad=pow(hash(uv),1.5) (mix(0.2,1.0,rad)), then snap p -= sdfNormal(p)*brainSDF(p)*0.85. Additive overlap of thousands of short-lived particles funneling through the same sulcus builds visible glowing neural tracts and a dense core \u2014 not evenly spaced dots. For the moat, replace the procedural shell seed with the baked memory-graph: targetB texture = PCA/UMAP(memory_embeddings)->[-1,1]^3, per-particle density weighted by importance_score, color by recency, so the densest bright pathways ARE Sam's most-connected memories.\n\nBREATHING: float pulse=0.5+0.5*sin(uTime*2.0); restore=6.0+3.0*pulse (shell tightens on systole); flow += -sdfNormal(p)*brainSDF(p)*restore; and film thickness += 60.0*pulse so hue breathes with the beat (~0.32 Hz heartbeat).",
"liquidCursorSpec": "Four forces in ONE velocity FBO pass, all gated by pointer SPEED (not position) so a still cursor barely perturbs and a fast swipe carves a healing hole. JS feeds uMouse (UV pos), uMouseVel (delta), uMouseSpeed (EMA-smoothed): const dx=mx-pmx,dy=my-pmy; let raw=hypot(dx*aspect,dy); speed=speed*0.85+raw*0.15; speed*=0.92 (idle decay->heal); uMouseSpeed=min(speed*gain,cap). On no-pointer (mobile), drive a Lissajous ghost cursor (mx=0.5+0.3*cos(t*0.7), my=0.5+0.3*sin(t*1.1)) so the brain parts itself.\n\nIn the velocity FS, accumulate into accel then velocity-Verlet integrate:\nvec2 q=(pos.xy-uMouse); q.x*=uAspect; float fall=exp(-dot(q,q)/(uRadius*uRadius)); // Gaussian splat, soft edge\nvec2 rdir=normalize(pos.xy-uMouse+1e-5);\naccel.xy += rdir*fall*uPushK*uMouseSpeed; // (1) repulsion splat, uPushK~0.0023..0.02\nvec2 tangent=vec2(-rdir.y,rdir.x); // 90deg rotate == cross with +Z\nfloat swirlSign=sign(uMouseVel.x*rdir.y - uMouseVel.y*rdir.x);\naccel.xy += tangent*swirlSign*fall*uSwirlK*uMouseSpeed; // (2) vortex swirl, uSwirlK~1x uPushK -> flick spins eddy\naccel.xyz += (uTargetPos - pos.xyz)*uSpringK; // (3) HEAL: Hooke pull to brain-home, uSpringK~0.003..0.02\naccel.xyz += curlNoise(pos)*uFlowK; // (4) always-on ambient brain flow (the SDF curl above)\nvel.xyz = (vel.xyz + accel*uDt) * uDamping; // damping 0.7..0.92; crit-damp target ~1-2*sqrt(uSpringK)\nvel.xy *= min(1.0, uMaxSpeed/length(vel.xy)); // per-axis clamp = stable at any dt\n// position FS: pos.xyz += vel.xyz*uDt;\n\nThe heal returns to uTargetPos = the brain/memory-graph home texture, so it re-forms the actual graph, not a generic sphere. Combining soft speed-gated splat + signed swirl + brain-home spring + ambient SDF-curl in one Verlet pass is what reads as parting LIQUID with surface tension; public demos ship only one of these.",
"colorSpec": "Physical thin-film structural color so it reads as living tissue/soap-film, not HSV rainbow dots. Constructive-interference wavelength w = 2*n*d*cos\u03b8 where film thickness d is DRIVEN by curl/velocity magnitude (fast neural traffic = thicker film = shifted hue) and \u03b8 is the view angle vs the SDF normal \u2014 so color is a function of MOTION and VIEW, shimmering as it pulses and parallaxes. Convert wavelength->RGB with the verified spectral_zucconi6 six-parabola fit (NOT naive HSV):\n\nvec3 bump3y(vec3 x, vec3 yo){ vec3 y=1.0-x*x; return max(y-yo,0.0); }\nvec3 spectral_zucconi6(float w){ float x=clamp((w-400.0)/300.0,0.0,1.0);\n const vec3 c1=vec3(3.54585104,2.93225262,2.41593945), x1=vec3(0.69549072,0.49228336,0.27699880), y1=vec3(0.02312639,0.15225084,0.52607955);\n const vec3 c2=vec3(3.90307140,3.21182957,3.96587128), x2=vec3(0.11748627,0.86755042,0.66077860), y2=vec3(0.84897130,0.88445281,0.73949448);\n return bump3y(c1*(x-x1),y1)+bump3y(c2*(x-x2),y2); }\n// render frag:\nfloat cosTheta = abs(dot(vViewDir, vSdfNormal));\nfloat thickness = 280.0 + vCurlMag*180.0 + 60.0*pulse; // nm; curlMag from sim, breathes with heartbeat\nfloat w = clamp(2.0*1.35*thickness*cosTheta, 400.0, 700.0); // n=1.35 film IOR\nvec3 iridescent = spectral_zucconi6(w);\n\nFRESNEL RIM (backlit-organ silhouette): float fres=pow(1.0-clamp(dot(vSdfNormal,vViewDir),0.0,1.0),2.5); vec3 rim=mix(vec3(0.15,0.10,0.45),iridescent,fres); float brightness=0.25+1.6*fres (edges ~7x brighter than core). Core stays indigo, grazing-angle silhouette flares into the full spectrum tracing the sulci wrinkles. Because rim/iridescence both use the SAME analytic SDF normal as the sim, the glow precisely traces YOUR organic shape \u2014 a clone with different seeds blows out to white or reads sparse.",
"shaderChanges": [
"POSITION FBO shader: change from `position += velocity` Euler to velocity-Verlet half-step \u2014 read updated velocity texture, `pos.xyz += vel.xyz * uDt` only; carry life in .w, decrement by uDelta*0.05, and on life<0 call sampleShellPoint(uv) to reseed center-weighted onto the brain SDF shell (this is what creates density turnover and bright tracts).",
"ADD a dedicated VELOCITY FBO shader (GPUComputationRenderer two-variable position+velocity dependency, matching the house pattern): accumulate the 4 forces (Gaussian speed-gated repulsion splat, signed tangential swirl, brain-home Hooke spring to uTargetPos, ambient SDF-curl) into accel, then `vel = (vel + accel*uDt)*uDamping` with a per-axis speed clamp. Add the breathing term `-sdfNormal(p)*brainSDF(p)*(6.0+3.0*pulse)` and the firing-ripple impulse from uEvent.",
"ADD brainSDF/sdfNormal/potential/curlNoise GLSL (replacing the freefloating box curl) so flow is tangent to the cortex \u2014 this is the single biggest starfield->organ move; reuse the same sdfNormal in BOTH the velocity sim and the render vertex shader.",
"RENDER vertex shader: pass vSdfNormal=sdfNormal(pos), vViewDir=normalize(cameraPosition-worldPos), vCurlMag=length(flow) (write curl magnitude from sim into an unused channel), vAlpha=clamp(speed*1.2,0.04,0.8); gl_PointSize = uSize*(0.6+2.0*vAlpha)*(300.0/-mvPosition.z) so near/fast particles dominate density. Add per-particle staggered-reveal delay from simplex(targetPos) and size-pop sin(p*PI) for the entrance.",
"RENDER fragment shader: compute spectral_zucconi6 thin-film iridescence (thickness from vCurlMag+pulse), Fresnel rim mix, soft gaussian sprite `float soft=exp(-3.0*dot(uv,uv)); if(dot(uv,uv)>1.0) discard;`, premultiplied low energy `vec3 col=rim*brightness; float energy=soft*vAlpha*0.6; gl_FragColor=vec4(col*energy, energy)` so additive OVERLAP builds dense colored mass instead of blowing out to white. Add the dissolve-frontier emissive band (uEdgeBoost>1.0) for the entrance sweep.",
"MATERIAL (JS): THREE.ShaderMaterial { blending:AdditiveBlending, depthTest:true, depthWrite:false, transparent:true } \u2014 order-independent additive sum, no per-frame CPU depth sort (keeps 65k at 60fps).",
"UnrealBloom retune in scene.ts: strength ~0.85, radius ~0.55, threshold ~0.62 \u2014 threshold high enough that only accumulated sulci hot-spots + rim bloom into a continuous membrane while the dim shell stays as fine texture (not a lens flare)."
],
"buildSteps": [
"Create apps/dashboard/src/lib/graph/neuralFlow.ts as the WebGL2 GPGPU hero (separate from CPU particles.ts and from the WebGPU Memory Cinema storm.ts \u2014 DO NOT touch MemoryCinema/cinema/*). Import GPUComputationRenderer from 'three/examples/jsm/misc/GPUComputationRenderer.js' (confirmed present at three@0.172).",
"Set up GPUComputationRenderer with 256x256 = 65,536 particles, two variables texturePosition (xyz+life) and texturevelocity (xyz+curlMag); wire setVariableDependencies([position,velocity]) both ways. Seed initial positions as a scattered curl cloud and bake targetA (VESTIGE wordmask via offscreen canvas, alpha>0.5 pixels) + targetB (brain SDF shell points, or for real users a precomputed PCA/UMAP DataTexture of memory_embeddings with importance_score density).",
"Author the position + velocity GLSL fragment shaders per shaderChanges: brainSDF/curlNoise block, 4-force velocity-Verlet accumulation, center-weighted reseed, breathing pulse, firing-ripple uEvent.",
"Author the render ShaderMaterial (vertex passes SDF normal/viewDir/curlMag/staggered-delay; fragment does spectral_zucconi6 + Fresnel rim + soft sprite + premultiplied energy). Set AdditiveBlending, depthWrite:false. Attach to a THREE.Points reading the position texture.",
"Wire the entrance timeline: GSAP (or rAF lerp) drives uFormProgress 0->1 (easeOutExpo 1.2s), uDissolve for the word->dust beat, and a target swap A->B at ~1.4s; expose uEdgeBoost for the dissolve-frontier glow. Land at formed+breathing+first-fire by t=3s.",
"Wire the input layer: pointermove -> uMouse/uMouseVel/uMouseSpeed with EMA(0.85/0.15) + idle decay(0.92) + aspect correction; no-pointer -> Lissajous ghost cursor. Wire firing events: on Vestige retrieve/create (or a Poisson timer weighted by importance_score) set uEvent=vec4(nodePos, uTime) so a bright iridescent ripple travels the cortex.",
"Retune UnrealBloomPass in scene.ts (strength 0.85 / radius 0.55 / threshold 0.62). Mount neuralFlow as the hero, swap out / keep the legacy starfield behind a feature flag.",
"Add graceful degradation: detect WebGL2; on low-end (devicePixelRatio cap, frame-time probe) drop to 128x128=16,384 particles and skip the second glow-halo sprite; ensure static-shippable (no server, all textures baked at build or hydrated from a shipped JSON of memory-graph coords). Verify 60fps live in the running app and capture proof.",
"Run gates: pnpm --filter @vestige/dashboard check && build; load the page and confirm formation hook, liquid cursor, and 60fps via the running app before claiming done."
],
"perfNotes": [
"65,536 = 256x256 FBO is the sweet spot; depthWrite:false + AdditiveBlending gives order-independent transparency so NO per-frame CPU depth sort (a sort at 65k would blow the frame budget). Keep this \u2014 it is the 60fps enabler.",
"brainSDF is evaluated multiple times per particle (sdfNormal does 4 SDF taps, curlNoise does 6 potential evals = up to ~24 SDF calls/particle/frame). Keep the SDF cheap (2 ellipsoids + one sin product); do NOT add raymarched detail. If frame-time spikes, drop curlNoise epsilon taps from 6 to a 3-tap variant (al-ro style cross(grad0,grad1)).",
"Reuse the SAME sdfNormal result between sim and render by writing it to a spare texture channel rather than recomputing in the vertex shader, if profiling shows the vertex SDF eval is hot.",
"velocity-Verlet + per-axis speed clamp (vel *= min(1.0, uMaxSpeed/length(vel))) is mandatory: naive Euler explodes the spring+repulsion on dt spikes (tab refocus / slow frame) and breaks graceful degradation. Pass real dt, clamped to ~33ms max.",
"Degrade path: WebGL2-only (ships everywhere per three@0.172); on devicePixelRatio>2 or measured <50fps, halve to 128x128 (16,384), drop the glow-halo second sprite, and lower bloom radius \u2014 keeps the brain alive on mobile/low-end.",
"Bloom is the most expensive post pass; threshold 0.62 limits the bloomed pixel count to rim+hot tracts only. Do not lower threshold below ~0.55 or the whole field blooms and both perf and the colored-density read collapse to white.",
"Premultiplied low per-particle energy (soft*vAlpha*0.6) is load-bearing for BOTH look and perf: it keeps additive overlap building hue instead of saturating, so you don't need HDR tonemapping gymnastics to keep the iridescence visible in dense zones."
]
}