import { MathUtils, Vector3 } from 'three'; import { Sky } from 'three/addons/objects/Sky.js'; import { SCENE } from '../constants/scene.ts'; import { NIGHT_SKY } from '../constants/nightSky.ts'; import { cloudShader, skyCloudFragment } from './clouds.ts'; export function createSky() { const mesh = new Sky(); const fragment = mesh.material.fragmentShader; const start = fragment.indexOf('// Clouds'); const end = fragment.indexOf('gl_FragColor = vec4( texColor, 1.0 );', start); if (start < 0 || end < 0) throw new Error('Sky cloud shader integration needs updating'); const nightBackground = `texColor += vec3(${NIGHT_SKY.backgroundRadiance.map(value => value.toFixed(3)).join(', ')}) * (1.0 - smoothstep(-0.07, 0.05, vSunDirection.y));`; mesh.material.fragmentShader = cloudShader + fragment.slice(0, start) + nightBackground + skyCloudFragment + fragment.slice(end); mesh.scale.setScalar(SCENE.skyRadius); const uniforms = mesh.material.uniforms; uniforms.turbidity.value = 2.5; uniforms.rayleigh.value = 2; uniforms.mieCoefficient.value = SCENE.mieCoefficient; uniforms.mieDirectionalG.value = SCENE.mieDirectionalG; uniforms.showSunDisc.value = 0; uniforms.cloudCoverage.value = 0; return { mesh, update(direction: Vector3, altitude: number, cloudCover = 0) { uniforms.sunPosition.value.copy(direction).multiplyScalar(SCENE.skyRadius); uniforms.rayleigh.value = MathUtils.lerp(2.5, 1.7, MathUtils.smoothstep(altitude, -6, 30)); uniforms.cloudCoverage.value = cloudCover; }, }; }