globe/src/globe.ts

114 lines
3.6 KiB
TypeScript

import {
SphereGeometry,
Texture,
Mesh,
MeshPhongMaterial,
Object3D,
TextureLoader,
Color,
DirectionalLight,
Shader,
ShaderMaterial,
} from 'three';
import { plainText as vertexShader } from './shaders/earth.vert';
import { plainText as fragmentShader } from './shaders/earth.frag';
export class Globe extends Object3D {
private sphere = new SphereGeometry(1, 32, 32);
private earthMaterial?: ShaderMaterial;
public earthMesh?: Mesh;
private loader = new TextureLoader();
public async loadTexture(name: string) {
return new Promise<Texture>((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.earthMaterial = new MeshPhongMaterial();
// this.earthMaterial.onBeforeCompile = (shader) => {
// let fragment = shader.fragmentShader;
// let vertex = shader.vertexShader;
// vertex = injectBefore(
// vertex,
// 'void main() {',
// `uniform vec3 lightDirection;\nvarying vec3 surfaceToLight;\n`
// );
// vertex = injectBefore(
// vertex,
// '#include <logdepthbuf_vertex>',
// 'surfaceToLight = mat3(modelViewMatrix) * lightDirection;\n'
// );
// fragment = injectBefore(
// fragment,
// 'void main() {',
// `varying vec3 surfaceToLight;\nuniform sampler2D nightmap;\n`
// );
// fragment = replaceWith(fragment, '#include <map_fragment>', '');
// fragment = injectBefore(
// fragment,
// '#include <lights_phong_fragment>',
// `
// vec4 sampledDiffuseColor = texture2D(map, vUv);
// vec4 sampledDiffuseColorNight = texture2D(nightmap, vUv);
// diffuseColor *= sampledDiffuseColor;
// `
// );
// fragment = injectBefore(
// fragment,
// '#include <output_fragment>',
// `float cosineAngleSunToNormal = dot(geometryNormal, surfaceToLight);
// cosineAngleSunToNormal = clamp( cosineAngleSunToNormal * 1.0, -1.0, 1.0);
// float mixAmount = cosineAngleSunToNormal * 0.5 + 0.5;
// outgoingLight = mix(sampledDiffuseColorNight.xyz, outgoingLight, mixAmount);
// `
// );
// console.log(fragment);
// shader.uniforms.nightmap = { value: textures[1] };
// shader.uniforms.lightDirection = {
// value: light.position.clone(),
// };
// shader.fragmentShader = fragment;
// shader.vertexShader = vertex;
// };
// this.earthMaterial.map = textures[0];
// this.earthMaterial.normalMap = textures[3];
// this.earthMaterial.specularMap = textures[4];
// this.earthMaterial.specular = new Color('grey');
this.earthMesh = new Mesh(this.sphere, this.earthMaterial);
this.add(this.earthMesh);
}
public tick() {}
}