I’m working on some code to draw 3D images of the moon at various phases, showing libration effects as well. At this point, my image of a first quarter moon looks like this:
Which looks very nice, but the transition from light to shadow is too gradual. As there is no atmosphere on the moon, the transition from light to dark should be more abrupt.
This is the code I have so far:
private drawMoonWebGL(context: CanvasRenderingContext2D, solarSystem: SolarSystem, time_JDE: number,
cx: number, cy: number, size: number, pixelsPerArcSec: number, pixelRatio: number,
parallacticAngle?: Angle, observer?: ISkyObserver, _showEclipses?: boolean): void {
if (!this.renderer)
this.setUpRenderer();
if (size === 0)
size = MAX_LUNAR_ANGULAR_DIAMETER * pixelsPerArcSec * 60;
if (this.webGlRendererSize !== size) {
this.renderer.setSize(size, size);
this.webGlRendererSize = size;
}
const phase = solarSystem.getLunarPhase(time_JDE);
const libration = solarSystem.getLunarLibration(time_JDE, observer);
this.camera.position.z = libration.D * KM_PER_AU;
this.camera.rotation.z = (parallacticAngle ? parallacticAngle.radians : 0);
this.globeMesh.rotation.y = to_radian(-libration.l);
this.globeMesh.rotation.x = to_radian(libration.b);
this.sun.position.x = 93000000 * sin_deg(phase); // Very rough, but adequate for the task!
this.sun.position.z = -93000000 * cos_deg(phase);
this.renderer.render(this.scene, this.camera);
context.drawImage(this.renderer.domElement, cx - size / 2, cy - size / 2);
}
private setUpRenderer(): void {
const globe = new SphereGeometry(MOON_RADIUS, 50, 50);
globe.rotateY(-PI / 2);
this.camera = new PerspectiveCamera(MAX_LUNAR_ANGULAR_DIAMETER / 60, 1, 0.1, 500000);
this.scene = new Scene();
this.globeMesh = new Mesh(globe, new MeshLambertMaterial({ map: new CanvasTexture(this.moonImageForWebGL) }));
this.scene.add(this.globeMesh);
this.renderer = new WebGLRenderer({ alpha: true, antialias: true });
this.sun = new DirectionalLight('white', 1.5);
this.sun.position.y = 0;
this.scene.add(this.sun);
this.scene.add(new AmbientLight('white', 0.15));
}
The above code takes an equirectangular moon map (courtesy of NASA) like this:
…and wraps it around a sphere so it can be rotated and illuminated in various ways.
With the searching for answers I’ve done so far I’ve only found information regarding one object casting shadows on a different object. I can’t find anything about adjusting the shadows on a single object with a single main light source.
There’s a little bit of ambient lighting added by my code (representing “earth shine”) to make sure the shadowed part of the moon isn’t pitch black, but removing that ambient lighting doesn’t sharpen the shadow boundary very much at all.
Can anyone tell me what I should to adjust to get the sharper shadow boundaries I’m looking for?