feat: evolve portfolio into an authored midnight grand tour

This commit is contained in:
2026-09-05 03:55:18 +03:00
parent 642f5b583d
commit c9ac36e249
41 changed files with 812 additions and 65 deletions

View File

@@ -33,7 +33,7 @@ export function createSun(resources: SceneResourceBag): SunWorld {
uTime: { value: 0 },
uDriveEnergy: { value: 0 },
};
const geometry = resources.own('geometry', new THREE.CircleGeometry(74, 128));
const geometry = resources.own('geometry', new THREE.CircleGeometry(112, 128));
const material = resources.own('material', new THREE.ShaderMaterial({
uniforms,
vertexShader: `
@@ -72,16 +72,18 @@ export function createSun(resources: SceneResourceBag): SunWorld {
float scanPhase = fract(vSunUv.y * uScanBands + sin(uTime * 0.08) * 0.008);
float scanBand = smoothstep(0.09, 0.18, scanPhase)
* (1.0 - smoothstep(0.72, 0.82, scanPhase));
float bandCut = mix(1.0, 0.54 + scanBand * 0.46, lowerDisc * 0.78);
float bandCut = mix(1.0, 0.06 + scanBand * 0.94, lowerDisc);
float horizonFade = smoothstep(0.015, 0.13, vSunUv.y);
float radialCore = 1.0 - smoothstep(0.02, 0.48, radius);
float luminance = verticalHeat
* (1.08 + uWarmth * 0.16 + uRouteProgress * 0.045 + uDriveEnergy * 0.045);
vec3 warmCore = mix(uColor, vec3(1.0, 0.61, 0.43), uWarmth * 0.18 + uRouteProgress * 0.035);
vec3 core = mix(uColor * 0.78, warmCore * 1.12, radialCore * 0.58);
vec3 warmCore = mix(uColor, vec3(1.0, 0.56, 0.32), smoothstep(0.25, 0.92, vSunUv.y) * 0.84);
vec3 core = mix(uColor * 0.82, warmCore * 0.83, smoothstep(0.05, 0.86, vSunUv.y));
core = mix(core, core * mix(0.82, 1.13, internalField), 0.54);
core = mix(core, uHazeColor * 0.72, limb * 0.22 + lowerDisc * 0.055);
gl_FragColor = vec4(core * luminance, softEdge * bandCut * horizonFade);
#include <tonemapping_fragment>
#include <colorspace_fragment>
}
`,
transparent: true,
@@ -92,7 +94,7 @@ export function createSun(resources: SceneResourceBag): SunWorld {
}));
const disc = new THREE.Mesh(geometry, material);
disc.name = 'horizon-sun';
disc.position.set(0, 48, SUN_DISTANCE_Z);
disc.position.set(0, 60, SUN_DISTANCE_Z);
group.add(disc);
const limbMaterial = resources.own('material', new THREE.ShaderMaterial({
@@ -116,6 +118,8 @@ export function createSun(resources: SceneResourceBag): SunWorld {
float ring = smoothstep(0.405, 0.475, radius)
* (1.0 - smoothstep(0.475, 0.515, radius));
gl_FragColor = vec4(uColor * (0.72 + uEnergy * 0.07), ring * (0.22 + uEnergy * 0.025));
#include <tonemapping_fragment>
#include <colorspace_fragment>
}
`,
transparent: true,
@@ -182,8 +186,8 @@ export function createSun(resources: SceneResourceBag): SunWorld {
limbMaterial.uniforms.uEnergy.value = energy;
haloMaterial.opacity = 0.105 + palette.warmth * 0.05 + energy * 0.015;
bleedMaterial.opacity = 0.055 + palette.warmth * 0.03 + energy * 0.01;
halo.scale.set(330 + energy * 18, 232 + energy * 10, 1);
disc.position.y = 48 + palette.warmth * 9;
halo.scale.set(480 + energy * 18, 360 + energy * 10, 1);
disc.position.y = 60 + palette.warmth * 14;
limb.position.y = disc.position.y;
halo.position.y = disc.position.y;
bleed.position.y = 7 + palette.warmth * 3;