114 lines
3.6 KiB
TypeScript
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() {}
|
|
}
|