diff options
| Commit | 71db9a7a0a240a6d4ba81dd0c4a4941385419339 (patch) | |
|---|---|---|
| Author | 2023-12-15 07:37:36 +0200 | |
| Committer | 2023-12-15 07:37:36 +0200 | |
| Files | 1682f50c2c1440da2be7011d4c26d0097ecf3f55 /src/blog | |
| syndamia.com-71db9a7a0a240a6d4ba81dd0c4a4941385419339.tar syndamia.com-71db9a7a0a240a6d4ba81dd0c4a4941385419339.tar.gz syndamia.com-71db9a7a0a240a6d4ba81dd0c4a4941385419339.zip | ||
| Parent | f5f7078e46ca28342d069d48b986583bc2cc0269 (diff) | |
(blog/bhs) Major rewrite of most text
1 files changed, 139 insertions, 102 deletions
| -rw-r--r-- | src/blog/difficulties-of-making-a-black-hole-shader/index.md | 241 |
diff --git a/src/blog/difficulties-of-making-a-black-hole-shader/index.md b/src/blog/difficulties-of-making-a-black-hole-shader/index.md index 7c78c05..b142f99 100644 --- a/src/blog/difficulties-of-making-a-black-hole-shader/index.md +++ b/src/blog/difficulties-of-making-a-black-hole-shader/index.md @@ -2,128 +2,153 @@ ## Contents -This year I took a university elective course for WebGL programming. -Back in August I had to create and submit some sort of a project, so I chose to create an interractive and animated black hole demo. -The primary idea was to show how the gravitational pull of black holes bend light and how the result looks from different points of view. +Back in August I had to submit a project for an elective WebGL programming course in university. +I chose to create an interractive and animated black hole demo. +The primary idea was to show how the gravitational pull of black holes "bend" light and how the result looks from different points of view. -During development I found a lot of hurdles, primarily with the actual bending of light. -Information online is kind of hard to understand and find, so I'll try my best to lay out everything I know. +During development I found a lot of hurdles, primarily with the actual mathematics behind it. +Information online is difficult to parse and understand if you don't have a physics background, so I'll try my best to lay out everything I know. -I'll assume you don't understand a lot of physics, but are familiar with vectors and operations with them. -Also this is in no way an exploration of best practices and good WebGL development. +I'll assume you don't know much about physics, but are familiar with mathematics and at the very least vectors. -## Context - -This section serves as a quick refresher. +## Preface ### Brief introduction to computer graphics -Imagine a photo of a bottle: you can see the bottle, but you cannot rotate it, or change it's size, or modify it in any way, without having to download the image, fire up a comlicated image editing program and spend hours upon hours doing your modifications. -And it becomes even harder if you want to add or remove objects, say a table on which the bottle sits. +Image and video files store visual information in a "fixed" way: you get a huge array of colors, each connected to a particular pixel on your screen. +The objects in those mediums cannot be modified easily, and additions or subtractions are even harder to do, usually requiring an expert using a professional tools for hours, days, weeks or months on end. + +Computer graphics aims to offload a lot of the creator's workload by "generating" the images on the fly using a set of descriptions for our objects. +The idea is to define objects with some simpler geometric figures, then give those to the computer, which will in turn have to calculate what the precise color of every pixel in the resultant image should be. + +For example, we can represent a tin can (without a label) as a simple cyllinder. +Changing it's height or width is trivial: just change the corresponding property you pass to the computer, and it will handle the rest. + +Of course this system has it's limitations: the more detail you add to an object, the more difficult it is to crunch up the math. +And adding lighting with shadows, bloom, refractions and so on becomes even more demanding for the computer. -The main idea of computer graphics is to define your objects with some few but "abstract" values: the bottle is X tall, the base is Y wide, it has Z color, etc. and then a computer program has to take those values and "generate" the actual image. -Or to be more precise, for every pixel on the screen where you should be able to see the bottle, the computer calculates what the precise color of that pixel is. +Expanding on out tin can example, if you want an image with a tin can up close, with a bright light shining on it, showing the hunderds or thousands of small scratches, bumps and kicks from manufacturing and usage, alongside reflections and shadows, you'll swiftly find that computer graphics are not the correct tool for the job. -This allows us to dynamically change objects: if I wanna make the bottle shorter, I make X a smaller number, and the computer recalculates everything using the new height. -If I want to add or remove objects, I just give or remove the specific parameters that define those objects and tell the computer to recalculate the image again. + +*Image by Sun Ladder on [Wikipedia](https://commons.wikimedia.org/w/index.php?curid=5746428)* -As you might imagine, it's extremely difficult to calculate everything needed to show an image, and it takes an absurd amount of system resources and time. -That's why people decided to create a separate processing unit, just for rendering graphics: the [GPU](TODO). +Such an image contains way way too much detail the average computer to handle in reasonable time (some small fraction of a second). +However, computer generated graphics are still a very useful tools. +Thats why modern machines come with a processor, handling most tasks like running programs, managing internet traffic, etc. and a graphics card handling *only* graphical tasks. -A GPU is optimized on the hardware level for parallel computation (calculate multiple stuff at the same time), fast math with 3D points and matricies, and so on. -The tradeoff is that a GPU doesn't implement most of the normal stuff a [CPU](TODO) does. +A graphics card is a combination of a special processor (GPU), designed to be able to *only* compute stuff related to graphics, with the upside of doing so much much faster than a general purpose processor (CPU) could, and some memory for use exclusively by that GPU. -For this reason, programs written for GPUs are called "shaders". -Most often shaders are written in some "higher" level programming language, which is then translated via a graphics API or library to something the actual GPU can understand. -For comparison, in normal softare development you write a program (not a shader), which is then translated to something the CPU can understand via a compiler or interpreter. +Since the GPU is different on the hardware level, it accepts significantly different instructions than a normal processor does. +For this reason programs written for a graphics processing unit are called "shaders", rather than just "programs". + +Of course, higher-level programming languages have been designed, which can then be transformed into the GPU-specific instructions. +But, contrary to normal software development, we don't really have standalone "shader compilers", but graphics library which do the job, alongside TODO ### Brief introduction to WebGL One of the most popular such libraries is [OpenGL](TODO) with it's associated shader programming languages [GLSL](TODO) and [GLSL ES](TODO). -In the 2000s people decided it would be a good idea to add a graphics API/library to web browsers. -Skipping over a lot of history, [WebGL](TODO) was born and widely adopted. +In the 2000s people decided it would be a good idea to add a graphics API/library to web browsers, which later morphed into what we call today [WebGL](TODO). It serves as a "layer above" OpenGL: you write JavaScript code with which the browser tells OpenGL what to do. You would get a DOM object in which the graphics will be rendered, and a "context" object to which you'll pass down your shaders, shader parameters and change graphics settings. -## Theory behind black holes +## Theoretical and algorithmic background + +Using [Einstein's field equations](TODO), or to simplify our life, [Schwarzschild's metric](TODO), we can precisely calculate the curvatures in space(time) at every point around a massive stationary object, like a non-rotating black hole. +Of course, the computation would still be too laborious, so making an approximation using [celestial mechanics](TODO) and representing light as a particle (corpiscule), we can tame the physics into a simple algorithm. + +Of course, there are a lot more details, so let's back up a bit. + +### What is a black hole -As we know from physics, objects with mass create a gravitational field which "pulls" inwards everything around them. -However, [Einstein's general theory of relativity](https://en.wikipedia.org/wiki/General_relativity) showed that this isn't really a force which pulls, like with (eletro)magnetism, but more of an effect: mass changes the curvature of [spacetime](TODO), which by extension changes the geodesic's "curavture". +A black hole is an object in space, which "collapsed" down to an infinitely small point. +In other words, if you take something with mass (although it's incorrect, you may think of mass as the amount of atoms comprising the object) and compress it into a small enough size, then the forces between the atoms and even subatomic particles will not be strong enough to keep themselves intact and separate. -### Explanation of geodesics and gravitational lensing +You can think of atoms like magnetic marbles, all marbles are separated with empty space (due to the magnet force), so if you push on them, you can compress them so they get closer together. +However, you can continue pushing them together, after enough forces, they'll all start deforming into a small really dense block of metal. -Let's back up a bit, first think of a flat surface, like a table or a (flat) sheet of paper. +Outside analogies, keep in mind that this infinitessimal point has the same initial mass as the object which collapsed. +This has great consequences on gravity, but what is gravity anyway? + +### Geodesics, gravity and gravitational lensing + +Think of a flat surface, like a table or a (flat) sheet of paper. What is the shortest distance between two points? -Obviously, that's a straight line. +Obviously, that's a straight line segment. +If you then extend that segment, so it has an infinite length, it becomes a line. However, what if our surface isn't flat? Imagine two points on a sphere, what is the shortest distance between them? -You might be inclined to say that's also a straight line, but it really isn't: it's an arc of a circle! +You might be inclined to say that's also a "straight" line, but it really isn't: it's an arc of a circle!  [*Image by CheCheDaWaff on Wikipedia*](https://commons.wikimedia.org/w/index.php?curid=48187293) This circle is called a [great circle](https://en.wikipedia.org/wiki/Great_circle). -Looking at all possible great circles, we find they have an interesting property: their center (and radius) matches with the center (and radius) of the sphere. +The main problem with calling this arc a "spherical line segment" (and the great circle a "spherical line" or something similar) is that both objects have different properties. -Another big difference between this arc and a "line" is that lines can be parallel, but arcs cannot. -Again, the shortest distance between to points is a line *segment*, extend that segment into infinity and it becomes a line. -On a flat surface, we know that if you take two points and create the line passing through them, then there exists at least two other distinct points, whose line, crated from intersecting them, does not ever intersect the first line. -However, as we said, on a sphere all great circles have the same center and radius, so it doesn't matter which two pairs of points we take, their great circles must always intersect[^parallels-of-latitude]! +Looking at all possible great circles, we find that their center (and radius) matches with the center (and radius) of the sphere. +From this we can find the bigest difference: lines can be parallel, but great circles cannot. +A line is an extended segment, so if you extend two different arcs (which are the shortest distance between two pairs of points on the sphere) and get the great circles, those will always intersect[^parallels-of-latitude]. -In non-flat surfaces, the segment which has the shortest distance between two points is called a geodesic (in flat surfaces, a line is practically a geodesic, on spheres, great circles are geodesics). +Therefore, the general term for the shortest path between two points on a non-flat surface is (kind of) called a geodesic[^geodesics-are-local] (the arc on the sphere is a geodesic). We can now also define what it means to "go straight forwards": in flat surfaces we would say that means following a straight line, while on non-flat it means following a geodesic. -Going back to physics, what the General theory of relativity tells us is that gravity bends spacetime, the actual space, or 3D surface, in which the universe exists. -In effect, the geodesics in our space are also curved. -Therefore, if you are always travelling forward, perfectly following a geodesic, if you start passing an object of great mass, it's gravity will bend that geodesic, so even though you are always going forwards, you'll actually "turn" or follow a curve. +Going back to physics, what the General theory of relativity tells us is that objects with mass bend the physical space, or 3D surface, of the universe, and we call that gravity. +As a result, the geodesics too are curved, so even though you may be always moving forwards at the same speed, to an outside observer it will look like you turn and change speed. + +The amount by which and the size of the area which is affected depend on that object's mass and size. +Generally, if two objects have the same mass, the bigger one will bend less a larger portion of space, compared to the smaller one, which will bend a lot the smaller portion of space. + +Since a black hole is a single infinetly small point, then all of it's mass is concentrated on that point, making a really really **really** strong bend in a small (compared to a non-blackhole object with the same mass) area. +Strong enough in fact, that if you get too close, you will not be able to overwhelm gravity and "merge" into that infinitessimal point. -This is the exact effect a black hole produces: it's mass is so great and it bends space(time) **so much**, light can take a really sharp curve. -We call this [graviational lensing](TODO): +An interesting effect from gravity is that light (which always travells "forwards", so along a geodesic) also gets "bent", allowing an observer to view otherwise obstructed objects. +We call that [graviational lensing](TODO). +Though not unique to black holes, thats when the effect is strongest:  *(notice how the gray arrows show the path light travels from a galaxy that is behind (obstructed by) the black hole)* -I spent a good amount of time explaning that gravity doesn't curve object's path but spacetime itself, however, this distinction really matters for physics, in our simulation it requires significantly less computation and programmer effort if we assume the former. - -Then were all of these explanations a waste of time? -Not really, since physics works with the spacetime curvature, we'll have to do conversions/modifications to the formulae, so they behaves like a force that pulls on the object in motion. +The distinction that gravity doesn't change the direction or speed of an object "directly" (preserving the speed for light rays) is at upmost importance for physics. +However, in our simulation, it would be significantly simpler to assume the opposite, since to an outside observer (like the "player") the difference is indistinguishable. +Therefore, we would need to make some modifications to the proper physics equations. ### Finding a formula Now, how do we calculate the exact curvature a black hole produces? -General theory of relativity provides us with the [Einstein field equations](https://en.wikipedia.org/wiki/Einstein_field_equations), a complicated set of equations which allows us to calculate how spacetime curves around an object with large mass. +General theory of relativity provides us with the (really complicated) [Einstein field equations](https://en.wikipedia.org/wiki/Einstein_field_equations) for this exact problem. [Schwartzschild](TODO) solved these equations, assuming that the body with mass doesn't spin[^schwm-assumptions]. This solution is called the [Schwarzschild metric](https://en.wikipedia.org/wiki/Schwarzschild_metric). A black hole for which this (these) assumption is true is called a "Shwartzschild black hole". -This is the simplest solution to those equation, and a Schwartzschild black hole is the simplest type of black hole, so we're gonna use that. -Now, by definition, here is the Schwartzschild metric in Schwartzschild coordinates: +The Shwarzschild black hole is the symplest of it's type, so using the Schwarzschild metric should give us the least trouble. +Now, here is the metric in Schwartzschild coordinates:  **YOUCH!** -You might notice there are derivatives in this equation, as you might imagine, it's unbearably slow to calculate it, especially if we want our demo to run at at least 30 frames per second! -There is also another problem: Schwartzschild coordinates, our GPU works with normal cartesian coordinates, so we'll also have to do transform the coordinates. -We'll also need to transfrom the curved spacestime coordinates to cartesian, as if spacetime wasn't curved around the black hole. +The variables themselves aren't that bad: `c` is the speed of light, <code>τ</code> is time, <code>Ω</code>, `t` and `r` are Schwarzschild coordinates. + +However, as you can see, there are two big problems: we have to calculate derivatives (that's what the `d` signifies) and convert from Schwarzschild coordinates to normal (eucledian) coordinates, that the computer understands natively. +Both of those operations are **incredibly slow**, the average computer doesn't standa a chance at rendering anything in a reasonable amount of time. -I personally have zero clue how to deal with this monster. -Thankfully [Riccardo Antonelli](http://rantonels.github.io/starless/) was able to do all of our coordinate conversions and simplify the living crap out of that monster (using some approximations), turning it in a pretty small equation: +Thankfully [Riccardo Antonelli](http://rantonels.github.io/starless/) was able to do all of our coordinate conversions and simplify the living crap out of that monster (using some approximations with celestial mechanics), turning it into something digestible:  Question now is: how do we use it? -This turned out to be a much harder problem than it should have, I actually had to refer to [Dmitry Brant](https://dmitrybrant.com/2018/12/11/ray-tracing-black-holes)'s usage of [the formula for his own project](https://github.com/dbrant/BlackHoleRaytracer) as well as [Ricardo Antonelli's implementation](https://github.com/rantonels/starless/blob/7a0c3c4efdc0666f53dcfa48d310fb2164be2d1a/tracer.py). +This turned out to be a much harder problem than it should have, I actually had to refer [Ricardo Antonelli's](https://github.com/rantonels/starless/blob/7a0c3c4efdc0666f53dcfa48d310fb2164be2d1a/tracer.py) and [Dmitry Brant's](https://dmitrybrant.com/2018/12/11/ray-tracing-black-holes) implementation in their projects, alongside copus articles on wikipedia to fully grasp how to put it to work. ### Applying the formula to "bend" light's path First, how are we going to represent light? -The simplest way is to think of light as a small particle (or spaceship) travelling through space. -We'll move our particle by a tiny amount, and before moving it, we'll calculate how much the black hole changes it's direction and move the particle in that new direction. +The simplest way is to think of light as a small particle (which Newton called "corpiscule") travelling through space. +We'll move our particle by a tiny amount in a certain direction, then update the direction, accounting for gravity, and then repeat. +The direction, alongside the amount by which the particle moves can be represented with a single vector, which we'll call light's "velocity". -Referring at the formula again: +Referring to the formula again:  @@ -131,48 +156,49 @@ The <code>F<sup>→</sup></code> returns a force vector (`F` for "force" and Imagine you are pushing a box: you are applying some force to it in a "forward" direction. If you pull the box, you'll apply some force in a "backward" direction. -This force vector specifies how much and in what direction exactly the black hole is pulling on the light "particle". - -Although the function takes in only one argument, `r`, that doesn't mean that `h` and <code>r<sup>\^</sup></code> are some universal constants: they also need to be calculted and "passed" to the function. +This force vector specifies how much and in what direction exactly the black hole is pulling on the corpiscule. -`r` is the distance from the center of the black hole (the singularity) to the **current** position of the light "particle". +Although the function takes in only one argument, `r`, that doesn't mean that `h` and <code>r<sup>\^</sup></code> aren't also arguments: -`h` is the magnitude of the ["specific angular momentum"](https://en.wikipedia.org/wiki/Specific_angular_momentum) of the light "particle". +- `r` is the distance from the center of the black hole (the singularity) to the **current** position of the corpiscule. -"Normal" linear momentum specifies how much "force" at what speed it takes to stop (or change) the speed and direction of an object in linear motion (that's why it's in kg\*m/s). -Imagine a big heavy train going at a fast speed. -How do you forcefully stop it? +- `h` is the magnitude of the ["specific angular momentum"](https://en.wikipedia.org/wiki/Specific_angular_momentum) of the light "particle". + + "Normal" linear momentum specifies how much "force" at what speed it takes to stop (or change) the speed and direction of an object in linear motion (that's why it's in kg\*m/s). + Imagine a big heavy train on a perfectly straight rails going at a fast speed. + How do you forcefully stop it? + + You can put a *really* heavy barrier on the tracks, in front of the train. + Since the train is moving at a really great speed, this barrier will have to be much much heavier (with much more mass) than the train itself. + + Alternatively, you can "launch" something against the train, meaning you can put a second train, moving in the opposite direction of the first train, so they hit head-on. + Since the second train would also be moving, if it's travelling at the same speed and has the same mass as the first train, when they hit they would both stop. + If the second travells at twice the speed, then it can have half of the mass of the first to produce the same effect. + + The property with which we can "prove" why both a larger mass at no speed, and a smaller mass at a faster speed, can stop the train, is the momentum. + + Angular momentum specifies how much "force" at what speed it takes to stop (or change) the speed and directino of a rotating object. + Imagine the train scenario but on a circular track. + + The specific angular momentum is the angular momentum of an object, divided by it's mass. + It's magnitude kind of tells us which property is more prevalent in the momentum, the mass or the speed. + For the same angular momentum, a long (big magnitutde) *specific* angular momentum means our object is small and moves fast, while for a short (small magnitutde) *specific* angular momentum out object is large and moves slowly. + + In our case a light "particle" is being pulled by a stationary object of large mass (a Shwarzschild black hole), so rather than finding the angular momentum[^angular-momentum] and then dividing by the mass[^light-has-no-mass], we'll use another formula: + +  + + where **in this specific formula only** `r` is the vector from the center of the big mass (the singularity of the black hole) to the light "particle" and `v` is the velocity (direction and amount of speed) the light is travelling with. + + The cross product returns a vector, so we'll need to take the magnitutde of the result and plug that into the formula. + It's also important that **we calculate it only once, in the beginning**. + So, we shouldn't be calculating the magnitude of the specific angular momentum every time the light "particle" is moved, rather we calculate it once, after it gets close enough to be affected by the black hole. + +- <code>r<sup>^</sup></code> is the normalized ([unit](https://en.wikipedia.org/wiki/Unit_vector), hence the `^` on top) vector from the center of the black hole to the light particle: + +  -You can put a *really* heavy barrier on the tracks, in front of the train. -Since the train has a lot of momentum, this barrier will have to be much much heavier (with much more mass) than the train itself (when the train would be stationary). - -Alternatively, you can "launch" something against the train, meaning you can take a second train, and make it go in the opposite direction of the first train, so they hit head-on. -Since the second train would also be moving, that would add to it's momentum, and the second train wouldn't need to be much heavier than the first train. -In fact, if the second train travels at the same speed as the first, then the mass of both trains would suffice to be equal, and if it travels twice as fast, it would suffice if the second train has half the mass of the first. - -Angular momentum specifies how much "force" at what speed it takes to stop (or change) the speed and directino of a rotating object. -Imagine the train scenario but on a circular track. - -The specific angular momentum is the angular momentum of an object, divided by it's mass. -It kind of tells us which property is more prevalent in the momentum, the mass or the speed: for the same angular momentum, a high *specific* angular momentum means our object is small and moves fast, while for a small *specific* angular momentum out object is large and moves slowly. - -In our case a light "particle" is being pulled by a stationary object of large mass (a Shwarzschild black hole), so rather than finding the angular momentum[^angular-momentum] and then dividing by the mass[^light-has-no-mass], we'll use another formula: - - - -where **in this specific formula only** `r` is the vector from the center of the big mass (the singularity of the black hole) to the light "particle" and `v` is the velocity (direction and amount of speed) the light is travelling with. - -The cross product returns a vector, so we'll need to take the magnitutde of the result and plug that into the formula. -It's also important that **we calculate it only once, in the beginning**. -So, we shouldn't be calculating the magnitude of the specific angular momentum every time the light "particle" is moved, rather we calculate it once, after it gets close enough to be affected by the black hole. - -<code>r<sup>^</sup></code> is the vector from the center of the black hole to the light particle as a [unit](https://en.wikipedia.org/wiki/Unit_vector) vector (hence the `^` on top). - -This means that we normalize the vector, meaning divide it by it's magnitude (length): - - - -Finally, putting all needed variables together in one formula, we get: +Finally, putting all needed variables together in one proper function, we get: <!-- \begin{align*} @@ -186,7 +212,6 @@ Finally, putting all needed variables together in one formula, we get: -->  -where velocity of light "particle" means a vector, with the direction in which the light "particle" will travel, and a magnitude equal to the distance (speed) the light "particle" will travel in. As you may notice, this can be simplified, if we substitude <code>r<sup>^</sup></code>: <!-- @@ -200,11 +225,17 @@ As you may notice, this can be simplified, if we substitude <code>r<sup>^</s -->  +In effect, we pass the distance from the black hole to the corpiscule and the function returns how light's velocity changes. + Finally, we know what to give the formula, and what it will return. -Current question is: how do we use it's output? +The task at hand is making an algorithm which utilises it. For that we'll need to get familiar with black holes. -### Explaning black holes +### Properties of a black hole + +We'll be working with non-rotating stationary black holes, since those are the simplest and provide perfectly useable results. + +From the [no-hair conjecture](https://en.wikipedia.org/wiki/No-hair_theorem) we know that a stationary black hole Physics regards black holes as an infinitessimal (infinitely small) point with some huge amount of mass. From the mass we can derive three radii, which will be the backbone of our black hole: the event horizon, the photon sphere and [ISCO](https://en.wikipedia.org/wiki/Innermost_stable_circular_orbit). @@ -234,6 +265,7 @@ Putting them all together, we should expect light to travel like this:  *Animation by Hugo Spinelli on [Wikipedia](https://commons.wikimedia.org/w/index.php?curid=138168679)* + ### Putting everything together Finally, now we have everything we need to divise an algorithm for our light. @@ -256,6 +288,7 @@ An algorithm doing this would look a bit like this (in pseudocode, inspired by P \begin{align*} & p_{cbh} = \text{position of center of black hole}\\ & r_s = \text{Schwarzchild distance from } p_{cbn} \\ +& r_{ps} = \frac{2}{3}r_s \quad \text{(photon sphere)}\\ & r_{ISCO} = 3 r_s \\ \\ & p_l = \text{position of light "particle"}\\ @@ -264,9 +297,12 @@ An algorithm doing this would look a bit like this (in pseudocode, inspired by P & r_l = \| p_l-p_{cbh} \| \quad \text{(distance between black hole and light)}\\ & \text{If } r_l \leq r_{ISCO} : \\ & \quad h = \| r_l \cross v_l \|\\ -& \quad \text{Do maximum 100 times}:\\ -& \qquad \text{If } r_l < r_s : \\ +& \quad \text{LightMovesLimit} = \infty \\ +& \quad \text{Repeat maximum LightMovesLimit times}:\\ +& \qquad \text{If } r_l \leq r_s : \\ & \qquad \quad \text{return "Light never escapes"} \\ +& \qquad \text{If } r_l \leq r_{ps} : \\ +& \qquad \quad \text{LightMovesLimit} = 100 \\ & \qquad \text{If } r_l > r_{ISCO} : \\ & \qquad \quad \text{return "Light escaped black hole"} \\ & \qquad p_l = p_l + v_l \quad \text{(move light)}\\ @@ -283,6 +319,7 @@ as a reminder, here is the definiton of <code>F<sup>→</sup></code>:  [^parallels-of-latitude]: You might think about the latituginal lines on a globe, they are indeed parallel (equidistant), but if you take any two points on the same such line, the distance between them won't be the smallest. +[^geodesics-are-local]: This actually isn't completely true, a geodesic is the "locally shortest distance", I've skipped the details since they aren't really that important for our purpopses. More info can be found on [wikipedia](https://en.wikipedia.org/wiki/Geodesic#Introduction). [^schwm-assumptions]: He also assumed the body didn't have an electric charge and the [cosmological constant](TODO) is zero. These are way outside of my understanding and our purposes, so I skiped them for simplicity. [^isco]: It's not really true that gravity stopps affecting spacetime after the ISCO, even though things can orbit Earth that doesn't mean that Earth doesn't bend spacetime. However, for the purposes of a simple shader, this assumption produces perfectly useable results. [^angular-momentum]: Angular momentum is actually [defined using the cross product](https://en.wikipedia.org/wiki/Specific_angular_momentum#Definition) |