General relativity 1: Kerr black holes

Today’s dev blog is the first of several about our next big update, which we are calling “General Relativity”. We chose this name because most of the new features are related to Einstein’s theory of gravity or, more precisely, its real-time visualization in SE. This includes black holes, neutron stars, and white dwarfs, Alcubierre warp bubbles for spaceships, and wormholes (Wormholes are new to SE). But what is interesting is that SE will now render all of these phenomena based on real physics, rather than the fake (artistic) approximations that were used before. All of this is thanks to the genuine work of our new programmer Mykhailo Moroz, who developed a real-time 4D spacetime geodesic ray-tracer. In physics, a geodesic is the path of a probe particle (like a photon) in a curved spacetime. If you compute the photon path in the opposite direction (from observer to the skybox), you get the coordinates to sample skybox texture. This reverse approach is fast enough to be useful in real-time graphics, but it distorts stars in an unrealistic way: stars are stretched around the black hole, as if they are areal light sources.
Equatorial view of a Kerr black hole with spin 0.99 distorting the Milky way background (brightness is enhanced). Note the asymmetrical shape of its shadow. This is due to frame-dragging.
Polar view of a Kerr black hole with spin 0.99 distorting the celestial grid in background to visualize the frame-dragging effect.
Implementation details
Tracing geodesics in a curved space-time with Moroz’ code is almost done in real time. This means that we were able to achieve 60 fps in 4k at some distance from the black hole on an RTX 2080. Of course, we want it to run on weaker hardware too, so some tricks were implemented. First of all, we don’t really need to trace geodesics at the screen resolution, and doing this at 1/3 resolution speeds things up by a factor of 9. So we rendered the warp vector in a smaller render target during the first pass, then used it to warp the background in full resolution during the second pass. This little hack works very well, with the only problem being the edge of the black hole’s shadow. This shows sampling artifacts because it is computed in a lower resolution: it looks like the background warping is pixelated near the edge. The solution to this problem is straightforward: rendering the shadow edge in full resolution. This adds a minor impact on performance, but the result is real-time Kerr black holes with a sharp edge that can run at 100+ fps on a GTX 1060!
The background warping is done like before: it is a screen-space image displacement, with additional skybox sampling in places where the shader has no screen data. The closer you are to the event horizon, the more pixels are sampled from the skybox. The resolution of the skybox is configurable, as before (“Warp and reflections resolution” slider in the Graphics settings), and its update interval is affected by the “Black hole quality” drop-down menu. The resolution of the warp render target is also configurable, and there is another setting that makes a significant impact on performance, called “Gravitational lensing precision”. This is actually a modifier for the geodesic tracer step length. You can balance speed and quality to your taste using these two settings.
As a tip for video makers: when you capture a video with the built-in capture tool, tick “Set graphics to maximum”. This will set almost all settings to their maximum values during capture. For black holes, it sets gravitational lensing precision to 1 and disables the low-resolution pass, i.e. geodesic will be computed at screen resolution. To enable max graphics for external video capture tools, input “MaxGraphics” in SE’s console (without quotes).
Warp resolution comparison. Can you see any difference?
Left: resolution = 0.35, 120 FPS
Right: resolution = 1.0, 29 FPS
Rendered in 3840x2160 on an RTX 2080.
Watch a video where the camera flies around a Kerr black hole with spin 0.99:
Another interesting feature (which is not really useful in SpaceEngine, but has excellent potential for education) is that since the Kerr black hole shader implements generic Kerr-Newmann metrics, it is possible to add electrical charge to a black hole, or make its unitless spin greater than 1. This is unlikely to exist in reality, but leads to an interesting result, which the shader successfully renders: a naked ring singularity!
When a black hole has zero spin, it is called a Schwartzschild black hole: it has a point singularity in its center and a spherically symmetric event horizon surrounding it, with light passing near the horizon being warped in a spherically symmetric way. When we start adding spin, the central singularity takes the shape of a ring (a so-called “ringularity”), but it is still hidden behind the event horizon. At a (unitless) spin value of 1 or higher; however, the horizon disappears and the singularity becomes visible — a "naked singularity". For distant observers, a naked singularity with an extreme spin of 2-5 looks like a biconvex lens floating in space.
Naked singularity with spin 5. Note that the small loops are numerical precision artifacts; they don’t exist in reality.
Kerr-Neman metrics. I played with charge and spin in the editor. Note that the ringularity looks like a lens:
It is theorized that a ring singularity may be able to act as a “portal” to another Universe, or to another part of our own. Currently, it's possible to stitch the singularity of a Kerr black hole metric with another Kerr black hole metric located somewhere else, making it into a wormhole-like structure; however, we are currently working on the implementation of “real” Morris-Thorne wormholes, which will have actual gameplay use in SE (that is to say, they will be traversable by spaceships!).
We'll be sharing more details about wormholes in another blog post later this month, along with details about updates to Alcubierre warp bubbles, and something really special: volumetric accretion disks!
We expect to release the General Relativity update this summer. Stay tuned!