globe/src/atmosphere.ts

68 lines
1.8 KiB
TypeScript

import {
BackSide,
DirectionalLight,
Mesh,
Object3D,
ShaderMaterial,
SphereGeometry,
} from 'three';
import { plainText as vertexShader } from './shaders/atmosphere.vert';
import { plainText as fragmentShader } from './shaders/atmosphere.frag';
export class Atmosphere extends Object3D {
public Rayleigh = 0.0025;
public Mie = 0.0005;
public Exposure = 15.0;
public Scale = 1;
public ScaleDepth = 0.25;
public G = -0.95;
public Wavelength = [0.65, 0.57, 0.475];
public geom?: SphereGeometry;
public mesh?: Mesh;
public shader = new ShaderMaterial({
vertexShader,
fragmentShader,
side: BackSide,
transparent: true,
});
constructor(public innerRadius: number, public outerRadius: number) {
super();
this.Scale = 1 / (this.outerRadius - this.innerRadius);
this.setUniforms(this.shader);
this.initialize();
}
setUniforms(shader: ShaderMaterial) {
shader.uniforms.invWavelength = {
value: [
1 / Math.pow(this.Wavelength[0], 4),
1 / Math.pow(this.Wavelength[1], 4),
1 / Math.pow(this.Wavelength[2], 4),
],
};
shader.uniforms.outerRadius = { value: this.outerRadius };
shader.uniforms.innerRadius = { value: this.innerRadius };
shader.uniforms.Kr = { value: this.Rayleigh };
shader.uniforms.Km = { value: this.Mie };
shader.uniforms.ESun = { value: this.Exposure };
shader.uniforms.scale = { value: this.Scale };
shader.uniforms.scaleDepth = { value: this.ScaleDepth };
shader.uniforms.g = { value: this.G };
}
setLight(light: DirectionalLight) {
this.shader.uniforms.lightDirection = {
value: light.position.clone().normalize(),
};
}
initialize() {
this.geom = new SphereGeometry(this.outerRadius, 128, 128);
this.mesh = new Mesh(this.geom, this.shader);
this.add(this.mesh);
}
}