33 lines
1.5 KiB
TypeScript
33 lines
1.5 KiB
TypeScript
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;
|
|
},
|
|
};
|
|
}
|