SOURCE / PINNED RELEASE
Made of little things.
Poly Dogfight
- Release
- b8511ee374e3…
- Author-recorded commit
- 5579434b9d8b…
- License
- LICENSE
- Author’s source reference
- nostr://npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr/wss%3A%2F%2Fgit.napplet.soy%2F/n-44f63e5422b
Archive hash verified: bcadd2430d8ea2bc…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
import { BackSide, Color, Mesh, ShaderMaterial, SphereGeometry, Vector3 } from 'three';
import { PALETTE } from './palette.ts';
/** Gradient sky dome that follows the camera and orients to the local "up" on the planet. */
export function createSky(): { mesh: Mesh; update(cameraPos: Vector3, up: Vector3, sunDir: Vector3): void } {
const material = new ShaderMaterial({
side: BackSide,
depthWrite: false,
fog: false,
uniforms: {
uUp: { value: new Vector3(0, 1, 0) },
uSun: { value: new Vector3(0, 1, 0) },
uTop: { value: new Color(PALETTE.skyTop) },
uHorizon: { value: new Color(PALETTE.skyHorizon) },
uGlow: { value: new Color(PALETTE.skyGlow) },
},
vertexShader: /* glsl */ `
varying vec3 vDir;
void main() {
vDir = normalize(position);
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}`,
fragmentShader: /* glsl */ `
uniform vec3 uUp; uniform vec3 uSun; uniform vec3 uTop; uniform vec3 uHorizon; uniform vec3 uGlow;
varying vec3 vDir;
void main() {
float h = dot(normalize(vDir), uUp);
vec3 col = mix(uHorizon, uTop, smoothstep(-0.05, 0.55, h));
col = mix(col, uHorizon * 0.92, smoothstep(0.0, -0.4, h));
float sun = max(dot(normalize(vDir), uSun), 0.0);
col += uGlow * pow(sun, 8.0) * 0.35 + vec3(1.0, 0.97, 0.88) * smoothstep(0.9975, 0.999, sun);
gl_FragColor = vec4(col, 1.0);
}`,
});
const mesh = new Mesh(new SphereGeometry(2800, 24, 16), material);
mesh.frustumCulled = false;
mesh.renderOrder = -1;
return {
mesh,
update(cameraPos, up, sunDir) {
mesh.position.copy(cameraPos);
material.uniforms.uUp!.value.copy(up);
material.uniforms.uSun!.value.copy(sunDir);
},
};
}
