I just can't help myself. One of my favorite things to do with 3D is make astronomical simulations. I find the topic fun and 3D suits it. So I return to my retrograde motion simulator, but this time with Three.js.
For the Sun, I create an ambient light throughout the scene. This ambient light will give the Sun its color, which I specify with the
ambient
attribute for the Phong material that will play the role of the Sun's surface: var ambient = new THREE.AmbientLight(0xffffff);
scene.add(ambient);
var surface = new THREE.MeshPhongMaterial({ambient: 0xFFD700});
var star = new THREE.SphereGeometry(50, 10, 10);
var sun = new THREE.Mesh(star, surface);
scene.add(sun);
var sunlight = new THREE.PointLight(0xffffff, 5, 1000);
sun.add(sunlight)
That works to give the Sun a nice yellow, but to make it behave as a light source for the rest of the Solar System, I add a point light to the sun, making it fairly bright and extending well out into space (1000). To get the Phong materials to work, I need to use the WebGL renderer instead of the canvas renderer that I default most of my work to (for greater compatibility). I suppose in Gaming JavaScript that I will have to start with
MeshBasicMaterial
, which ought to be fine for the Sun. Not so much for planets.Anyhow, with that, I have my Sun:
Next up, I add my planets:
var surface = new THREE.MeshPhongMaterial({ambient: 0x000000, color: 0x0000cd}); var planet = new THREE.SphereGeometry(20); var earth = new THREE.Mesh(planet, surface); earth.position.set(250, 0, 0); scene.add(earth);Since I am using Phong materials, I get a nice dark-side of the Earth effect:
When I do the same for Mars, however, I notice that it is looking... stretched:
At first, I think that I will be forced to switch to an orthographic camera to deal with this. That is not necessarily a bad thing as it probably makes a little more sense for astronomy simulations. After all, the vast distances that are usually involved make "perspective" a quaint concept. But in this case, I don't have to introduce the difference between cameras. I had been setting the field of view for the camera to a rather wide 75°:
var camera = new THREE.PerspectiveCamera(75, aspect_ratio, 1, 10000);
camera.position.z = 500;
scene.add(camera);
Cutting that down (and moving back a bit), does the trick:I still may switch to the orthographic camera, but at least now I am not forced to.
Last up, is movement of the planets. Back when I was first doing these simulations, I would add the planet to a frame of reference and rotate the frame of reference. This time, however, I stick with simple geometry:
clock = new THREE.Clock();
function animate() {
requestAnimationFrame(animate);
var t = clock.getElapsedTime();
var e_angle = 3 * t * 0.1;
earth.position.set(250* Math.cos(e_angle), 250* Math.sin(e_angle), 0);
// Now, show what the camera sees on the screen:
renderer.render(scene, camera);
}
animate();
If memory serves, knowing the X-Y position in scene coordinate space will come in handy.And that does the trick:
That is a good stopping point for tonight. Up tomorrow, I will add cameras on the two planets to witness retrograde motion. And maybe some background stars.
Editable source code
Day #527
No comments:
Post a Comment