1

I'm trying to build a model of the upcoming total solar eclipse on Aug. 21 in THREE.js. Using NASA's SPICE toolkit, I was able to get extremely accurate rectangular geometric coordinates for the Sun and the Moon for each minute of the day, using the J2000 Earth-centered inertial frame.

After setting a DirectionalLight at the location of the Sun and pointing it at Earth, I was able to create a shadow that traverses the earth at the correct time and along the correct map, according to NASA. The trouble is that the shadow is MUCH larger than the small shadow of the moon in the umbra zone. As best I can tell, THREE.js is casting a uniform shadow over both the umbra and the penumbra:

My demo here (Wait about two seconds for the eclipse to start, please.) And here's the problem:

enter image description here

Nice diagram of the umbra and penumbra from this lecture: enter image description here

I've checked and double-checked the ephemeris data, and I don't believe the problem is that the Moon is too close or too large. I tried swapping out the light source for a SpotLight instead, which has a penumbra setting, but the shadow was extremely pixelated and, based on the official demo, it doesn't appear that the umbra is clearly distinguishable from the penumbra.

I thought the problem might be that the DirectionalLightShadow uses an Orthographic camera, but the grainy shadow I achieved with the SpotLight had the exact same size problem, though grainier.

My code for the directional light is pretty much out of the box:

var sunLight = new THREE.DirectionalLight(0xffffff, 1);
sunLight.decay = 1;
sunLight.intensity = 2;
sunLight.castShadow = true;
sunLight.shadow.mapSize.width = 1024 * 2;
sunLight.shadow.mapSize.height = 1024 * 2;
sunLight.shadow.camera.near = 0;
sunLight.shadow.camera.far = constants.AU * DISTANCE_SCALE * 10;
scene.add(sunLight);
sunLight.target = earth;

Complete source code

I don't understand shadowMaps well, so I'm hoping there's an under-the-hood way in THREE or WebGL to cast a shadow that only completely occludes the light source, as opposed to most of it. I'm not certain that's the problem here, but the resemblance of my shadow to the penumbra is awfully close.

WestLangley
  • 102,557
  • 10
  • 276
  • 276
Chris Wilson
  • 6,599
  • 8
  • 35
  • 71
  • 1
    [They're working on it.](https://github.com/mrdoob/three.js/pull/8933) Until then, you'll probably have to create the effect yourself. Perhaps create shapes and project them on to the globe's surface? Or create a shader which can take the size/radius of both your light source and the shadow source to calculate a fixed amount of darkening depending on whether the fragment is in the umbra/penumbra? Just a shot in the dark (heh). – TheJim01 Jul 18 '17 at 15:23
  • 2
    Your likely have precision problems. Your far plane is at 1 million or so. Near plane at 0.1. Push your far plane out as far as you can. Same with the shadow camera. Do not call `lookAt()` or rotate the shadow camera yourself. Do not use solar-system-scale units with three.js. Also, your directional light should never have an intensity > 1. Learn how to use the shadow camera helpers to maintain a tight shadow map and avoid pixelation. – WestLangley Jul 18 '17 at 17:16
  • I'm scaling down all the kilometers by a very heavy factor (10 ^ -5) -- that should help, right? – Chris Wilson Jul 19 '17 at 07:27
  • scale is not the only thing that can help ... using relative coordinates usually helps more see [ray and ellipsoid intersection accuracy improvement](https://stackoverflow.com/q/25470493/2521214) but all depends on the computations behind your rendering engine ... also this might interest your [Is it possible to make realistic n-body solar system simulation in matter of size and mass?](https://stackoverflow.com/a/28020934/2521214) – Spektre Jul 19 '17 at 15:10
  • Both extremely helpful, thank you! – Chris Wilson Jul 19 '17 at 21:27
  • Would adding four spotlight along the edges of the Sun be a performance nightmare? That might do the trick since penumbras and umbras are a function of the radius of the Sun – Chris Wilson Jul 20 '17 at 12:49
  • Trying that seems to have answered my question. Is it hopeless to have multiple spotlights? (The solution works perfectly for creating the umbra and penumbra, but crashes after 100 frames or so) – Chris Wilson Jul 20 '17 at 13:44
  • not sure if anything should be crashing after a certain amount of frames. You have so few geometry in here that you could probably get away with many 'lights', but three may limit you there. – pailhead Jul 25 '17 at 19:56

0 Answers0