Author: BL de Vries. PhD and Scientific visualisation advisor at SURF.
Here you find updates on the project!
I have released v0.0.1 for curvedpy, the numerical back-end used to calculate photon geodesics/trajectories. You can now install it through pip. See the repo here: curvedpy
I had a great time at the Blender Conference 2024 and enjoyed presenting my project to the people there. You can watch my talk online here:
Viewing a disk around a blackhole at different angles
Einsteins theory of general relativity is the theory that describes gravity, blackholes and the structure of our cosmos. In this theory energy curves space-time and in turn this curvature determines how matter as well as light moves. This means that if we want to properly make an image of a blackhole in Blender, we must include curvature in our ray tracing. I made a first version of a custom render engine that implements Einstein theory. And since I am an astrophysicist, I want it to be scientifically correct. No tricks, no effects and no shortcuts. Let me show you how I am using scientific techniques to build a custom engine that renders a realistic blackhole in a Blender scene.
Figure 2: shooting moons by the blackhole. See how multiple images can be seen of the same object! In Fig. 3 you can see what is going on in the Blender scene. |
Before we go into the math and physics, lets conceptually try to understand what happens in Fig. 1-3. The renders in Fig. 1-3 are made using a very simple Blender scene setup shown in Fig. 4. The scene contains a region in which space-time is curved due to a blackhole in the centre (the blackhole is about 1/60th in size compared to the sphere in Blender). The other four small spheres are the moon-like objects you see in the animation. And then there is a camera. That is all (note there is also an HDRI image not visible in the 3d view of Fig. 4).
Figure 4: Blender 3d scene view for the animations in Fig. 1 and 2 |
What the render engine does is outside the blackhole sphere of influence (indicated with red in Fig. 4) it uses the ray_cast function implemented in Blender. Thus, outside this sphere the space-time is flat. When the ray hits the sphere the hit location and direction are passed to the general relativistic ray tracer. This calculates how the light ray is continued in the curved space-time until it hits the boundary of the sphere again. It then gives back the location and direction with which it exits the sphere. From here on the ray_trace function in Blender is again used to continue the ray tracing.
In Fig. 5 examples are given in two dimensions of what happens inside the sphere where the space-time is curved. The rays start at x=-15
With the insights of Fig. 4-6 we can now interpret the animations and images in Fig. 1-3 better. I roughly divided the image of the blackhole with only an HDRI in four regions in Fig. 7. In the outer green region, you have very mild deflection of the lines of sight. In the blue region the lines of sight are more curved and lens the background galaxy in a circle around the centre. In the yellowish region the curvature is so strong that the lines of sight can angle 90 degrees or more outwards (see fig. 5 for examples). In these cases, you see the HDRI to the right/left/top/bottom sides of the blackhole or even de HDRI behind the camera (see the rays in Fig. 6). The inner black region is totally black because the lines of sight end on the blackhole.
You can see even better how the lines of sight are deflected when the moon-like object fly passed and behind the blackhole. You can often see these objects through two lines of sight, see Fig. 8. You see one of the moons to the left of the blackhole, but also smaller and more deformed to the right. This image on the right forms from lines of sight that are deflected by angles of the order of 90 degrees, like you see in Fig. 5.
Note: the numerical code is placed in a separate repository (https://github.com/bldevries/curvedpy). This will become a Python package installable using pip in future. (31 October 2024)
As of now the code is in development. The idea for the general structure of the code is to have a Python package (called curvedpy) which can be installed using pip and a Blender add-on with the render engine that can be installed in Blender. The Python package does the ray tracing in curved space-time, which means solving the differential equations and any optimalizations therefor. The Blender render engine will interface with Blender and deal with the scene information and the traditional ray tracing in flat space. This code structure might change depending on how I will incorporate rendering of objects inside curved space-time. This might require less separation between the curved and flat ray tracing.
This section is for those interested in the physics and maths. I will loosely explain how the path travelled by bodies in four-dimensional space-times is calculated given a metric. I will leave out most of the math and proper definitions. It needs to be readable by people that have studied some calculus and mechanics. If you have studied some General Relativity and/or differential geometry, please keep the goal of the oversimplifications I make in mind. :)
So, let’s start with Newtons second law. In flat space the motion of bodies (in the classical limit) is described by the second law of Newton:
Where F is the net force acting on the body, m is the body's mass and x is the location of the body. If no force is acting on the body this reduces to:
Which states that the velocity of the body is constant and
In General Relativity a similar equation as the second law of Newton exists and is called the geodesic equation:
This equation describes the motion of a body in four-dimensional space (thus including time). At first sight this equation does not look similar to Newtons second law but let’s have a look. As with Newtons equation the
Now
would not exist, the geodesic equation would reduce to Newtons equation (with F=0) and taking
The term with
(Note to self: Add more information on different and equivalent definitions of a straight line?)
The
Where
Even though you have used the metric of flat Euclidean space many times, you might not have realized. This is because the metric in Euclidian space is:
Here I have written the metric in Matrix notation. (For the connoisseur, the metric is a rank-2 tensor
Here we use standard matrix multiplication,
A nice example of a more complicated metric in a familiar setting is that of the surface of a sphere. If you are interested in what this metric looks like and how you can use it, see my blog Calculating lengths in curved spaces using SymPy’s symbolic mathematics, Python and Matplotlib.
One of the metrics implemented in curvedpy is the Schwarzschild metric that describes space-time around a spherically symmetric blackhole. In Spherical coordinates this looks like:
The package curvedpy uses the Schwarzschild metric in cartesian coordinates. To show this we create a SchwarzschildGeodesic class:
SW = cp.SchwarzschildGeodesic()
And we can show the metric by typing:
SW.g
The Christoffel Symbols
SW.gam_y
To see this working, check out the jupyter notebook version of this text.
For the code I have implemented I have used techniques from several peer-reviewed papers and books, among which:
- Bronzwaer et al 2018: https://arxiv.org/abs/1801.10452
- Davelaar et al 2023: https://arxiv.org/abs/2303.15522
- Moscibrodzka et al 2023: https://arxiv.org/abs/2302.02733
- A first course in general relativity. Bernard Schutz
- Spacetime and geometry. Carroll
Let me briefly explain how I solve the geodesic equation. The geodesic equation is a not quite linear second order differential equation, so we need to use some numerical techniques to tackle it. The scipy packages has some nice integrators which we can use through the function solve_ivp
. For a simple example of how you can use this function check out my blog Simply solving differential equations using Python, scipy and solve_ivp.
For solve_ivp
to work we need to split the geodesic equation in first order equations by introducing the "velocity"
Now we can integrate these equations (these are 8 equations since the indices can take on 4 values) if we have an initial condition for the location calc_trajectory
.
Ray Tracer / Physics
- Collisions inside curved spacetime
- Kerr Blackhole
- Red shift
- Polarisation
- V Add multisampling
- V Add a disk to the blackhole
- V Allow camera to enter curved spacetime region
- V Add a metric that spans the whole scene
- V Add the ability to render objects inside the curved space-time region
Science
- Finish parameter study
- Explore publication options
Testing:
- V Collect some characteristics of photon trajectories for testing
- V Add a flat metric to the curvedpy code to compare curved and non curved scenarios precisely
- V Add a color coding option in Blender to find "rogue" rays
Optimalization
- Tensorflow model or interpolation of some of the calculations
- V Commandline rendering
- V Run on snellius
- V Parallelization
Useability:
- Add Blender UI to the render engine
- Finalise the python package and upload to PyPi
- Add tests
- Make the render engine a proper add-on to Blender
- For a tutorial and example on how to use curvedpy see: Curvedpy_tutorial_and_examples.ipynb (coming soon!)
Not available yet, coming soon