Migrate Vite SPA to Hugo (hugo-coder, dark) with WebGPU background
- Hugo static site at root: config, content (home/about/resume/blog + 5 projects), data/resume.yaml, custom layouts (gpu background, resume renderer, projects list), dark theme with canvas behind content - gpu-bg/: extracted WebGPU/WebGL2 spiral engine as a Vite sub-package; slim bootstrap drops router/overlay/text renderer; fixed uniforms (scene0/dim0); self-contained engine.js - archive/: retired Vite SPA preserved (router, overlay, data, engine/text orphaned) - 3-stage Dockerfile (node -> hugo extended/dart-sass -> nginx), static nginx config - DEPLOYMENT.md handover + README rewrite; pre-hugo rollback tag
This commit is contained in:
108
gpu-bg/src/shaders/fullscreen.wgsl
Normal file
108
gpu-bg/src/shaders/fullscreen.wgsl
Normal file
@@ -0,0 +1,108 @@
|
||||
struct Uniforms {
|
||||
resolution: vec2<f32>,
|
||||
time: f32,
|
||||
scene: f32,
|
||||
mouse: vec2<f32>,
|
||||
date: vec4<f32>,
|
||||
sampleRate: vec4<f32>,
|
||||
stemMultipliers: array<vec4<f32>, 8>,
|
||||
};
|
||||
|
||||
@group(0) @binding(0) var<uniform> u: Uniforms;
|
||||
|
||||
struct VsOut {
|
||||
@builtin(position) pos: vec4<f32>,
|
||||
@location(0) uv: vec2<f32>,
|
||||
};
|
||||
|
||||
@vertex
|
||||
fn vs(@builtin(vertex_index) i: u32) -> VsOut {
|
||||
let p = array<vec2<f32>, 3>(
|
||||
vec2<f32>(-1.0, -3.0),
|
||||
vec2<f32>(-1.0, 1.0),
|
||||
vec2<f32>(3.0, 1.0),
|
||||
);
|
||||
let clip = p[i];
|
||||
var out: VsOut;
|
||||
out.pos = vec4<f32>(clip, 0.0, 1.0);
|
||||
out.uv = clip;
|
||||
return out;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fs(in: VsOut) -> @location(0) vec4<f32> {
|
||||
let res = u.resolution;
|
||||
let fragCoord = (in.uv * vec2<f32>(0.5) + vec2<f32>(0.5)) * res;
|
||||
|
||||
var uv = (fragCoord - 0.5 * res) / res.y;
|
||||
|
||||
let slowTime = u.time * 0.2;
|
||||
|
||||
let bgGrey = vec3<f32>(0.11, 0.11, 0.12);
|
||||
let cardGrey = vec3<f32>(0.30, 0.32, 0.36);
|
||||
let coreWhite = vec3<f32>(0.90, 0.95, 0.90);
|
||||
|
||||
// ---------- palette keyed by scene ----------
|
||||
let scene0 = vec3<f32>(0.20, 0.75, 0.20); // HERO – emerald
|
||||
let scene1 = vec3<f32>(0.85, 0.55, 0.20); // ABOUT – amber
|
||||
let scene2 = vec3<f32>(0.25, 0.60, 0.95); // PROJECTS – cobalt
|
||||
let scene3 = vec3<f32>(0.90, 0.35, 0.55); // CONTACT – rose
|
||||
|
||||
let sFloor = i32(clamp(floor(u.scene), 0.0, 3.0));
|
||||
let sCeil = i32(clamp(ceil(u.scene), 0.0, 3.0));
|
||||
var c0 = scene0;
|
||||
c0 = select(c0, scene1, sFloor == 1);
|
||||
c0 = select(c0, scene2, sFloor == 2);
|
||||
c0 = select(c0, scene3, sFloor == 3);
|
||||
var c1 = scene0;
|
||||
c1 = select(c1, scene1, sCeil == 1);
|
||||
c1 = select(c1, scene2, sCeil == 2);
|
||||
c1 = select(c1, scene3, sCeil == 3);
|
||||
let tBlend = u.scene - floor(u.scene);
|
||||
let sceneAccent = mix(c0, c1, tBlend * tBlend * (3.0 - 2.0 * tBlend));
|
||||
|
||||
// ---------- mouse-reactive distortion ----------
|
||||
let mousePos = (u.mouse - 0.5 * res) / res.y;
|
||||
let distMouse = length(uv - mousePos);
|
||||
let influence = exp(-distMouse * 7.0);
|
||||
uv += (mousePos - uv) * influence * 0.12;
|
||||
|
||||
let angle = atan2(uv.y, uv.x);
|
||||
let radius = length(uv);
|
||||
|
||||
let baseSpiral = angle + (radius * 8.0) - slowTime;
|
||||
let ripple = sin(radius * 15.0 - (u.time * 0.5)) * 0.08;
|
||||
let distortedSpiral = baseSpiral + ripple;
|
||||
|
||||
let armCount = 2.0;
|
||||
let rChannel = smoothstep(0.05, 0.55, abs(sin((distortedSpiral + 0.04) * armCount)));
|
||||
let gChannel = smoothstep(0.05, 0.55, abs(sin(distortedSpiral * armCount)));
|
||||
let bChannel = smoothstep(0.05, 0.55, abs(sin((distortedSpiral - 0.04) * armCount)));
|
||||
let patternChannels = vec3<f32>(rChannel, gChannel, bChannel);
|
||||
|
||||
let coreNeon = vec3<f32>(0.02 / (patternChannels + 0.025));
|
||||
let spiralColor = mix(cardGrey, sceneAccent, patternChannels.g);
|
||||
let primarySpiral = coreNeon * spiralColor;
|
||||
|
||||
let ringWave = sin(radius * 12.0 - (u.time * 1.5));
|
||||
let sharpRing = smoothstep(0.85, 0.95, ringWave);
|
||||
let ringMask = sharpRing * smoothstep(0.7, 0.1, radius);
|
||||
let secondaryRings = cardGrey * ringMask * 0.4;
|
||||
|
||||
let vignette = smoothstep(0.95, 0.4, radius);
|
||||
|
||||
var finalColor = bgGrey + secondaryRings;
|
||||
finalColor = mix(finalColor, primarySpiral, 0.85);
|
||||
|
||||
let centerLight = 0.015 / (radius + 0.02);
|
||||
finalColor += centerLight * coreWhite;
|
||||
|
||||
// soft cursor glow
|
||||
finalColor += exp(-distMouse * 4.0) * 0.03 * sceneAccent;
|
||||
|
||||
// ---------- dim when not on the home page (u.date.x controls it) ----------
|
||||
let dim = u.date.x;
|
||||
finalColor = mix(finalColor, vec3<f32>(0.0), dim);
|
||||
|
||||
return vec4<f32>(finalColor * vignette, 1.0);
|
||||
}
|
||||
Reference in New Issue
Block a user