import { SphereGeometry, Texture, Mesh, Object3D, TextureLoader, Color, DirectionalLight, ShaderMaterial, } from 'three'; import { plainText as vertexShader } from './shaders/earth.vert'; import { plainText as fragmentShader } from './shaders/earth.frag'; import { Atmosphere } from './atmosphere'; export class Globe extends Object3D { private sphere = new SphereGeometry(1, 128, 128); private atmosphere = new Atmosphere(1, 1.05); private earthMaterial?: ShaderMaterial; public earthMesh?: Mesh; private loader = new TextureLoader(); public async loadTexture(name: string) { return new Promise((resolve, reject) => { this.loader.load(`/${name}`, resolve, undefined, reject); }); } public async loadArray(names: string[]) { return Promise.all(names.map((name) => this.loadTexture(name))); } public async initialize(light: DirectionalLight) { const textures = await this.loadArray([ 'earth/2k_earth_daymap.jpg', 'earth/2k_earth_nightmap.jpg', 'earth/2k_earth_clouds.jpg', 'earth/2k_earth_normal_map.jpg', 'earth/2k_earth_specular_map.jpg', ]); this.earthMaterial = new ShaderMaterial({ fragmentShader, vertexShader, uniforms: { light: { value: light.position }, texture0: { value: textures[0] }, texture1: { value: textures[1] }, normalmap: { value: textures[3] }, specularMap: { value: textures[4] }, shininess: { value: 1.0 }, specular: { value: new Color('gray') }, }, }); this.atmosphere.setUniforms(this.earthMaterial); this.atmosphere.setLight(light); this.earthMesh = new Mesh(this.sphere, this.earthMaterial); this.add(this.earthMesh); this.add(this.atmosphere); } public tick() {} }