A friend recently recommend Liu Cixin’s amazing Three-Body trilogy to me, and I am almost done reading the third book. The second book of the series, The Dark Forest, contained an alien spacecraft that I immediately wanted to visualize. I highly recommend this trilogy, and will try to avoid spoilers as much as possible!
The vessel I am referring to is the Trisolaran probe or `droplet’, which is described as a teardrop-shaped craft, about 3.5 meters long, made of a type of exotic matter called ‘strong-interaction material’. Its surface appears to be perfectly reflective at all wavelengths.
In this post I’ll describe the way I create images of the probe. I only use freely available software (Blender, Python) and assets (a star map from ESA). I’ll share the source files at the end of the post.
Rendering the space probe will entail two basic ingredients:
1) A model for the space probe itself, with a reflective material;
2) A high-resolution, 360-degree stellar background, which is the environment for the probe to reflect.
We may later choose to add the Sun, the Earth, or other vessels. For now, let’s assume the probe is on its way to Earth through interstellar space.
Part I: The probe
First, let’s discuss the geometry. The book mentions a ‘perfect teardrop’ shape, rounded at the head and pointy at the tail.
Wolfram Mathworld gives a formula for a teardrop curve:
Wolfram Mathworld also shows a plot of this curve, for a number of values of :
I immediately liked what I saw here!
Which value for did the Trisolarans choose? Here, we have some artistic freedom. To find a curve I like, I implemented the previous equations in Python, making one small modification: I decreased the scale in the -direction to 40% of the normal value, to create a thinner, leaner teardrop (note that the image from Wolfram Mathworld does the same – the x and y-axes are scaled differently!)
Plotting that curve for , we get:
Our next step is to model this curve in Blender. To do so, open a new file in Blender, delete the standard cube, switch to a top view, drag in the figure we just created in Python, and center it in the viewport. Then, add a new Bezier curve to the scene. As if fate had intended it, Blender will create a teardrop-shaped curve:
I then added two vertices – a total of four seems to be enough. I adjusted the coordinates of the first and last vertex to be on the x-axis exactly (y-coordinate 0), so that when we revolve the curve, all center vertices lie at the same location and we can merge them:
Then, place all vertices on the curve and adjust their handles to obtain a good approximation:
Make sure to set a high number of segments for the Bezier curve, so that it is nice and smooth.
Next, add a Screw modifier, again increasing the number of segments to create a smooth result:
Finally, define a reflective material, which is easily done:
Now, we turn to the environment that the probe will reflect.
Part II: The stars
Rendering stars in a nice way is an interesting topic in itself, which I will cover in a future blog post. For now, we will turn to a high-resolution map (a staggering 40,000 by 20,000 pixels, in fact!) provided by ESA, which is not a perfect solution, but it does allow us to create high-resolution (8K) images. We need such high resolutions, because our camera’s field of view is limited, so we only see a fraction of the sky, which we still want to look nice, requiring an enormous total resolution. The map must also cover the entire sky, because the probe’s reflection will show a large portion of the celestial sphere.
Finally, experience has shown that, to make an interesting image, we really want some extended structures, not just stars. A high-resolution map of the Galaxy, in an equirectangular projection, seems like a good choice. Fortunately, ESA provides such a map – in 20K! See this link – the (working) download links are on the right-hand side of the page.
All we have to do is download this .png image and set it as a 360-degree environment map in Blender:
We are now ready to behold the Trisolaran probe! Setting Blender’s viewport to ‘display render preview’ creates a satisfying live visualization of the probe in its natural habitat (note that in Blender 2.8, the Eevee renderer has to be selected for this to work). Adjust the environment map’s “Strength” parameter to control the overall brightness of the scene.
The final step is to find a satisfactory camera perspective and to render an image. For the final render, I chose the Cycles engine with 4000 samples per pixel; this high number is needed to remove the noise in the reflected images of the stars. I encountered a small visual artifact in the final renders (a small section of the reflected image appeared a bit distorted/stretched), which may be due to numerical rounding or perhaps a small bug in Blender. At any rate, I removed this slight blemish in Photoshop to produce the renders below.
8K, 4K, 2K renders
“The Milky Way was reflected on its surface as a smooth pattern of light that gave the mercury droplet a pure beauty.”
-Liu Cixin, The Dark Forest
Python script for drawing teardrops
ESA stellar map