Summary Files Commits Branches @commit @diff @stats
path: root / src / blog
diff options
context:
space:
mode:
Commit5accc983088aee1e1e45eae706cf3584e43df9aa (patch)
Author
 Syndamia <kamen@syndamia.com>
2024-08-01 14:02:11 +0300
Committer
 Syndamia <kamen@syndamia.com>
2024-08-01 14:02:11 +0300
Filesa05124b5e999bc89071b2c0bcd54f09acfe5e2d2 /src/blog
syndamia.com-5accc983088aee1e1e45eae706cf3584e43df9aa.tar
syndamia.com-5accc983088aee1e1e45eae706cf3584e43df9aa.tar.gz
syndamia.com-5accc983088aee1e1e45eae706cf3584e43df9aa.zip
Parent14526cb38d986bd190b9308ed0695c3b614c5ace (diff)
(blog/tpbhs) Rewrote first half of post
1 files changed, 95 insertions, 249 deletions
-rw-r--r--src/blog/the-physics-behind-a-black-hole-shader/index.md344
diff --git a/src/blog/the-physics-behind-a-black-hole-shader/index.md b/src/blog/the-physics-behind-a-black-hole-shader/index.md
index 555744a..a517cdf 100644
--- a/src/blog/the-physics-behind-a-black-hole-shader/index.md
+++ b/src/blog/the-physics-behind-a-black-hole-shader/index.md
@@ -1,98 +1,136 @@
-# Difficulties of making a black hole shader
+# The physics behind a black hole shader
## Contents
-1. [Preface](#preface)
- 1. [Brief introduction to computer graphics](#brief-introduction-to-computer-graphics)
- 2. [Brief introduction to WebGL](#brief-introduction-to-webgl)
-2. [Theoretical and algorithmic background](#theoretical-and-algorithmic-background)
- 1. [What is a black hole](#what-is-a-black-hole)
- 2. [Geodesics, gravity and gravitational lensing](#geodesics-gravity-and-gravitational-lensing)
- 3. [Finding a formula](#finding-a-formula)
- 4. [Applying the formula to "bend" light's path](#applying-the-formula-to-bend-lights-path)
- 5. [Properties of a black hole](#properties-of-a-black-hole)
- 6. [Putting everything together](#putting-everything-together)
-3. [WebGL preparation](#webgl-preparation)
-4. [Shader](#shader)
+1. [What do the physics say?](TODO)
+ 1. [What is gravity?](TODO)
+ 2. [What does it mean to bend space?](TODO)
+ 3. [How to solve the EFEs?](TODO)
+ 4. [What is a black hole?](TODO)
+2. [Finding a formula](TODO)
+3. [Applying the formula to “bend” light’s path](TODO)
+ 1. [Properties of a black hole](TODO)
+4. [Light-bending algorithm](TODO)
5. [Appendix](#appendix)
-Back in August I had to submit a project for an elective WebGL programming course in university.
+Back in August 2023 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 "bends" light and how the result looks from different points of view.
-During development I found a lot of hurdles, primarily with the actual mathematics behind it.
-Information online is difficult to find and understand without having a physics background, so I'll try my best to lay out everything I know.
+Then in the December of that same year, I sat down and started writing a blogpost, explaning how some of the more complicated parts were made.
+Funnily enough, I started finding errors... a *lot* of errors.
+
+As it turned out, my implementation was completely wrong, but somehow I fudged the formulas around in just the right way to make it *look* correct.
+So the post got delayed and sparsely rejuvenated over the following months.
+
+For this reason I chose to take up two related electives this year: one on general relativity and one on raytracing, with the hopes of gaining enough understanding of the material to rework the original solution into something proper.
+
+This article represents the first of a two-part series about this very shader.
+Here, we'll talk about physics and how to generally model them.
+In the second part, we'll explore raytracing and computer graphics with WebGL.
I'll assume you don't know much about physics, but are familiar with mathematics and at the very least vectors.
-## Preface
+## What do the physics say?
+
+The "big words" version of what we're going to explore is:
+
+Using [Einstein's field equations](TODO), we can precisely calculate the curvatures in space(time) at every point around a black hole.
+Obviously we're going to use [Schwarzschild metric](TODO) on a (Schwarzschild) black hole.
+To further simplify our calculations, we can make approximations using [celestial mechanics](TODO).
+
+Now, let's try and unravel everything.
+
+### What is gravity?
+
+Everything with mass applies a "pulling" force to everything else with mass.
+It's easy to see this is true, but we get into trouble when trying to find formula which predict/calculate that pulling force.
+
+Newton gave it a good shot, with his [3 laws of motion](https://en.wikipedia.org/wiki/Newton%27s_laws_of_motion), which proved to be correct for about a century and a half.
+They even helped the discovery of Neptune, since measurements showed that the orbit of Uranus didn't meet expectations if there wasn't another planet meddling with things.
+The real crux of the issue came when the same problem occured with [Mercury's orbit](https://en.wikipedia.org/wiki/Mercury_%28planet%29#Advance_of_perihelion), but no new planet was found.
+
+As it turned out, Newton's formulae had only been approximations, they worked when light (and therefore [causality, or the speed at which changes propagate](https://www.youtube.com/watch?v=msVuCEs8Ydo)) had infinite speed.
+
+Albert Einstein's general theory of relativity showed that gravity wasn't a "force which pulled", it was actually an effect which **bent** space.
+And that only happened because the speed of light wasn't infinite.
+
+### What does it mean to bend space?
+
+Think of a flat surface, like a table.
+What is the shortest distance between two points?
+Obviously, that's a straight line segment.
+If you then extend that segment, so it has an infinite length, it becomes a line[^line-definition].
+
+[^line-definition]: This is the mathematical definition of a line, obviously in conversation we refer to a line segment as a line. But this distinction will be useful.
-### Brief introduction to computer graphics
+However, what if our surface isn't flat?
+Imagine two points on a sphere, what is the shortest distance between them?
+Obviously, it's an arc of a circle and extending it to it's maximum possible length, we get a [great circle](https://en.wikipedia.org/wiki/Great_circle).
-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 professional tools for hours, days or weeks on end.
+![](https://upload.wikimedia.org/wikipedia/commons/thumb/c/cb/Illustration_of_great-circle_distance.svg/480px-Illustration_of_great-circle_distance.svg.png)
+*Image by CheCheDaWaff on [Wikipedia](https://commons.wikimedia.org/w/index.php?curid=48187293)*
-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 primary properties of simpler geometric figures, like the points on a triangle, 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.
+Now, what does it mean to go "forwards"?
+On a flat surface, we can define it as "following a (straight) line segment", on our sphere we can say "following an arc of a great circle".
-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.
+Better yet, in geometry there are [geodesics](TODO), the general term for a curve on any surface which is the shortest[^geodesics-are-local] path between any two points.
+So now we can say "going forwards means going along a geodesic".
-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.
+[^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).
-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.
+It's important to note that an arbitrary geodesic doesn't have most properties you might be used to.
+For example, on a flat surface, we can have parallel lines, but on our sphere, great circles will always intersect[^parallels-of-latitude].
-![](https://upload.wikimedia.org/wikipedia/commons/thumb/a/a8/Empty_tin_can2009-01-19.jpg/514px-Empty_tin_can2009-01-19.jpg)
-*Image by Sun Ladder on [Wikipedia](https://commons.wikimedia.org/w/index.php?curid=5746428)*
+[^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.
-Such an image contains way way too much detail for 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 graphics card handling *only* graphical tasks (alongside a processor, handling all other tasks like running programs, managing internet traffic, etc.).
+Another important effect is that every N-dimentional object can be curved in N+1-dimentions.
+Meaning, a 1D line can be bent into a 2D squigle.
+A 2D plane can be bent into a 3D curvature.
+But what that really means is, for the N-dimentional being, it can view the effects of this change, without begin able to percieve the entire change.
-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.
+Imagine a flatlander, some creature living in a 2D plane, which can only look at thing on the X and Y coordinates.
+If we fold this flat plane into a 3D sphere[^sphere-plane-homeomorphism], that creature can calculate the change, but it can't understand or imagine what a 3D sphere is, since it only thinks and percieves in 2D.
-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".
+[^sphere-plane-homeomorphism]: In reality, [math shows this cannot be done](https://old.reddit.com/r/math/comments/152kfq/is_it_possible_to_form_a_flat_plane_into_a_sphere/c7iqo6p/) without making important changes to the plane. But this serves as a decent-enough intuitive example.
-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
+This means the same thing can happen with our 3D space.
+It can get bent into a more-complicated 4D shape, we can calculate the exact object and understand it on a mathematical level, but we cannot truly envision it.
-### Brief introduction to WebGL
+This is what gravity does, it *somehow* changes the curvature of space.
+We can't really imagine or see it, but we can understand and work with it in practice as the **bending of our geodesics**.
-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, which later morphed into what we call today [WebGL](TODO).
+The resultant effect is that if you travel perfectly forwards in a spaceship and pass by an object with mass (like a planet) from a close enough distance, your path will be curved, without you steering your ship.
-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.
+Einstein gives us the necessary equations for those geodesics, the [Einstein Field Equations](TODO).
-## Theoretical and algorithmic background
+### How to solve the EFEs?
-&&important I haven't formally studied physics, so don't fully trust anything here.
- There are most definetly errors, steming from my lackluster understanding.
+This problem of not being able to see or imagine 4D space is quite significant, since we have our equations, but it's incredibly difficult to assign them to reality.
+Schwartzchild solved them for a universe where there is only one particle with mass in the 1910s, then in the 1960s the equations were solved with one spinning particle with mass, and that's it.
-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 Schwarzschild black hole.
-Unfortunetly, the computation would still be too laborious, so we'll need to make an approximation using [celestial mechanics](TODO).
+There are plenty of mathematical solutions, but these are the only ones which have been connected to the physical phenomena.
+Generally we call a solution a metric, since that's the main mathematical "function" we get.
-That is the overall gist of the underlying physics, but I promised an explanation, so let's back up a bit.
+That's why we'll work with that initial Schwartzschild metric, which assumed a non-rotating single mass.
+And that's what defines Schwartzchild blackholes too.
### What is a black hole
-Before we even begin to talk about gravity and light, we need to understand how atoms work.
-Imagine a set of marbles, scattered on a table.
+Let's imagine atoms as a set of marbles, scattered on a table:
![](https://upload.wikimedia.org/wikipedia/commons/thumb/0/0e/Marbles_from_Indonesia.jpg/1280px-Marbles_from_Indonesia.jpg)
*Image from By Okkisafire on [Wikipedia](https://commons.wikimedia.org/w/index.php?curid=30338734)*
-Now, start pushing on all of them from the edges of the table to it's center.
+Now, start pushing from all sides of the table to it's center.
In the beginning, you'll mostly roll them, until they all get in contact with each other.
-At that point (assuming they all stay flat on the table), the glass will keep the marbles together, handling your force.
+At that point (assuming they all stay flat on the table), the glass will keep the marbles together, it's strength opposing your force.
By increasing the force with which you push on them, after a certain threshold, the glass will break, turning the marbles into shards.
Those shards will still have some fight in them, so after increasing your force by another level, you'll turn all of those shards into tiny glass granules.
A similar occurence happens with atoms.
-Normally atoms are spread apart, by pushing them together, at a certain point (ignoring the orbitin electrons) all nuclei will be "touching" and the [nuclar force](TODO) will keep them together.
+Normally atoms are spread apart, by pushing them together, at a certain point (ignoring the orbiting electrons) all nuclei will be "touching" and the [nuclar force](TODO) will keep them together.
By increasing your pushing force you can overwhelm the nuclear force and "shatter" the nuclei into their subatomic particles.
Assuming an enormus explosion doesn't happen, and you can keep increasing your force, it's also possible to overwhelm the "subatomic forces" that keep those subatomic particles "together"[^matter-together].
@@ -106,47 +144,6 @@ That point is called a **black hole**.
This object is very bizzare, generally it doesn't have too much properties, but the ones it has are really unique.
In my case of computer graphics, the only important part is it's effect on light.
-### Geodesics, gravity and gravitational lensing
-
-To understand how black holes affect light, we first need to understand how black holes affect gravity.
-
-Think of a flat surface, like a table.
-What is the shortest distance between two points?
-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?
-Obviously, it's an arc of a circle and extending it to it's maximum possible length, we get a [great circle](https://en.wikipedia.org/wiki/Great_circle).
-
-![](https://upload.wikimedia.org/wikipedia/commons/thumb/c/cb/Illustration_of_great-circle_distance.svg/480px-Illustration_of_great-circle_distance.svg.png)
-*Image by CheCheDaWaff on [Wikipedia](https://commons.wikimedia.org/w/index.php?curid=48187293)*
-
-Now, what does it mean to go "forwards"?
-On a flat surface, we can define it as "following a (straight) line segment", on our sphere we can say "following an arc of a great circle".
-But what we really need is a more generalized definition, which handles both of our cases (and more).
-
-That's why in geometry there is the notion of [geodesics](TODO), the generalized curve on any surface which (roughly speaking) is the shortest[^geodesics-are-local] path between any two points.
-On a flat surface, that's the line segment, on the sphere it's the great circle arc.
-It's important to note that a general geodesic cannot have most properties you might be used to from "the shortest path between two points".
-For example, on a flat surface, we can have parallel lines, but on our sphere, great circles will always intersect[^parallels-of-latitude].
-
-And there are a lot more complicated surfaces, imagine a flat surface but with half-spherical "trophs" in it, on the flat segments your geodesic would be the line segment, but on those trophs it will be an arc (of a great circle).
-Actually, you don't need to imagine: the entire universe is a 3D surface, which is mostly flat, but has sherical-ish "trophs" in it.
-
-That's one of the primary results from the General theory of relativity, normally the universe's surface is nice and flat, but objects with mass "produce" gravity, which some sort of a force[^gravity-isnt-a-force] that bends our surface and creates those trophs, changing the local geodesics.
-The resultant effect is that if you travel perfectly forwards in a spaceship and pass by an object with mass (like a planet) from a close enough distance, your path will be curved, without you steering your ship.
-
-Here comes the meat of this section: if you have no outside references (if all planets and stars are invisible), you, in your ship, *wouldn't* really be able to tell your path is curved.
-But to a (stationary) outside observer, like another spaceship, it *would* look like you've turned.
-In fact, while "turning" it will look like you've slowed down, since an arc is always longer than a straight line segment, but you're travelling at the same speed.
-
-For the cherry on top, light is also affected by gravity, and we know it's speed is constant and always travels forwards, therefore gravity "bends" light.
-
-
-
-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 affect a larger portion of space, but will bend it less, compared to the smaller one, which will affect a smaller portion, which will be bend a lot.
Since a black hole is a single infinetly small point, then all of it's mass is concentrated on that point, making it bend a relatively small are of space **a lot**.
Strong enough in fact, that if you get too close, you will not be able to overwhelm gravity and "merge" into that infinitessimal point (the white lines are our "geodesics"):
@@ -171,7 +168,7 @@ However, in our simulation, it would be significantly simpler to assume the oppo
Therefore, in our simulation, we'll have light rays, but when they approach a black hole, their speed and direction would change.
This will be determined by some physics equations.
-### Finding a formula
+## Finding a formula
Now, how do we calculate the exact curvature a black hole produces?
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.
@@ -199,7 +196,7 @@ I will not be trying to explain why or how the Schwarzschild metric and this for
Question now is: what do all of those letters represent?
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
+## Applying the formula to "bend" light's path
Our plan for simulating gravitational lensing is to move the corpiscule by a tiny amount in a certain direction by a certain amount, update the direction and amount according to gravity, rince and 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".
@@ -300,8 +297,7 @@ Putting them all together, we should expect light to travel like this:
![](https://upload.wikimedia.org/wikipedia/commons/2/27/Black_Hole_Shadow.gif)
*Animation by Hugo Spinelli on [Wikipedia](https://commons.wikimedia.org/w/index.php?curid=138168679)*
-
-### Putting everything together
+## Light-bending algorithm
Finally, now we have everything we need to divise an algorithm for our light.
For light we'll store two vectors: one for it's position and one for it's velocity.
@@ -325,154 +321,6 @@ as a reminder, here is the definiton of <code>F<sup>&rarr;</sup></code>:
![](./img/antonelli-formula-expanded.png)
-## WebGL preparation
-
-The course was focused on handmade solutions, so some of the logic uses a [custom handmade library](TODO).
-
-Since the primary component was the shader itself, I made sure to simplify my logic to the absolute minimum.
-A **lot** of decisions were made to optimize development time, without considering how good they were.
-
-In a scene there really are only 3 distinct objects: the stars, the black holes and the skybox.
-The latter is just a simple cube, inside which everything resides, if a ray doesn't hit anything of interest, it will hit the cube.
-Both stars and black holes are simple spheres, the former with an orange-y color (#f4803b) and any radious.
-Black holes aren't rendered and their underlying sphere has the same radius as the ISCO, so their purpose is for intersection checks (more on those when we get to the [shaders](#shaders)).
-
-Most JavaScript code isn't worth talking about, wherever possible I use the [course library](TODO) and where I can't it's mostly simple WebGL configurations, elementary object "classes" and trivial HTML handling.
-Though, there are still two somewhat interesting systems:
-
-### Scenes
-
-I wanted to have multiple scenes, with different arrangements of objects and with animations (stars moving around).
-For that I devised a dead-simple level loading and animation system.
-
-An object of type "Level" stores a name, description, location of camera (the viewer) and arrays for stars, black holes and animations.
-Though, for creating new levels, you only pass the first three:
-
-```javascript
-var level1 = new Level(
- "Star passing behind black hole", // Level title
- "The black hole warps the light", // Level description
- [1000,0,650]); // Initial coordinates of camera
-```
-
-Adding stars or black holes requires going through two member functions: `addStar` and `addBlackHole`.
-Both take the center of the object, as well as it's radius, alongside an animation function.
-The latter has two parameters: current time in TODO(seconds,milliseconds,?) from the beginning and the current object that will be created.
-This function is called on each frame with the appropriate arguments, so inside you'll have to "manually" modify the object's properties.
-
-For example, a simple star going forwards could be added like this (`vecSum` is just [componentwise vector summation](TODO)):
-
-```javascript
-level1.addStar([1070,0,1000], // Coordinates of center
- 10, // Radius
- (t, star) => vecSum(star.center, [-t,0,0])); // Move from left to right
-```
-
-Or one which rotates around a point:
-
-```javascript
-var speed = Math.PI / 20, rad = 40;
-level1.addStar([1000+rad,0,900],
- 3,
- (t, star) => vecSum([1000,0,900], [Math.cos(t*speed) * rad,
- Math.sin(t*speed) * 5,
- Math.sin(t*speed) * rad]));
-```
-
-For black holes it's the same.
-If you want the object to not move, you could just pass `undefined` as the function:
-
-```javascript
-level1.addBlackHole([1000,0,900], 30, undefined);
-```
-
-### Movement
-
-It wouldn't be fun without the ability to move around in the scene, so I added a simple system for that too.
-WASD moves the camera position forward, left, backward and right, shift moves down and space moves up, all relative to the current direction the camera is looking towards.
-Those are all done with relatively simple analytic geometry: we store three vectors, one pointing up, one pointing forward and one pointing left (which can be calculated from the other two with a cross product).
-To move forward, add to the position the forward vector times some constant, to move backwards subtract and so on.
-
-Looking around with the mouse was kinda tricky, since I decided to use [spherical coordinates](TODO).
-You store two angles, the "up" and "left" angle, moving the mouse forwards adds to the "up" angle, moving it downwards subtracts and so on.
-The tricky part was what to do after
-
-TODO
-
-## Shaders
-
-As a gentle reminder, in OpenGL we have a vertex shader and a fragment shader:
-
-- The vertex shader is ran on every point of every object in our scene
-- The fragment shader is ran on every pixel of your screen, with the added bonus that depending on the pixel, certain values are passed down from the vertex shader.
-
- This includes interpolated points: a line is made up of two points, the vertex shader is ran on both of them, then the line is interpolated and the fragment shader is ran on each pixel, corresponding to a point on the line.
- The vertex shader values are also passed down interpolated, so if one end of the line is the color red, while the other end is green, then the fragment shader corresponding to the pixel, which shows the middle of the line, will have the color yellow.
-
-### Vertex shader
-
-As already mentioned, black holes aren't rendered, so the only objects with special rendering are the stars.
-To simplify my life, I chose to do a simple [diffusion reflection](https://learnopengl.com/Lighting/Basic-Lighting), with the light source emminating from the camera, something which was already made in lectures:
-
-![](TODO)
-
-The result isn't amazing, but you can clearly make out the sphere as a 3D object (not a flat circle).
-
-### Fragment shader
-
-This is the meat of our logic, this is where we'll implement our algorithm:
-
-![](./img/algorithm.png)
-
-In real life, every star emits light, which then travells some distance, until it reaches our eyes.
-However, computing it this way is incredibly inefficient, for every star we'll have to create hundreds or thousands of light rays (corpiscules), most of which probably wont reach us.
-We want performance, so this is a no-go.
-
-The alternative is to do the opposite, assume every pixel was hit by a "ray" and trace back it's steps, if it came out of a star then it has some specific color (it was an actual ray), but if it didn't then show it as black (no ray hit us).
-Taking it further, how do we "trace back" those steps?
-Well, we can find the precise coordinate of every pixel inside the 3D scene, and move each point in the direction we're looking (though this image is about raytracing, just look at the two top red vectors):
-
-![](https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Ray_trace_diagram.png/800px-Ray_trace_diagram.png?20080214101526)
-*Image by Timrb on [Wikipedia](https://commons.wikimedia.org/w/index.php?curid=3553478)*
-
-In the context of computer graphics, this is called [ray marching](TODO).
-
-Now, how do we detect if the ray hit something?
-The dumb way is to move the ray forward a bit and check with every object whether the ray intersects it.
-However, since all of our objects are spheres, there is a very easy optimization and simplification - imagine the ray as an infinitely long line and just get the shortest (perpendicular) distance between it and the center of the sphere:
-
-TODO custom image #1
-
-For this we can implement a simple distance function:
-
-![](https://wikimedia.org/api/rest_v1/media/math/render/svg/42c53741fd3d8765e56ea652369a512a2cd09eac)
-
-```glsl
-float linePointDistance(vec3 a, vec3 n, vec3 p) {
- return length((p - a) - dot(p - a, n) * n);
-}
-```
-
-Where `a` is the coordinate of our ray (pixel), `n` is the direction it will be travelling in and `p` is the sphere center we're comparing with.
-
-However, there is a huge problem: our line extends in both directions, so a check like `linePointDistance(ray, step, center) <= radius` would also detect if the ray interects the point behind us (when ray is going in the opposite direction)!
-A very simple solution is to just add a sign to our distance: if positive then the distance is in reference to a point in front, while negative means it's behind.
-The simplest way to get this information is by taking the [dot product](TODO) between our "forwards" direction and the direction from our coordinates to the [projection](TODO) of our point on the line:
-
-TODO custom image #2
-
-```glsl
-float linePointDistance(vec3 a, vec3 n, vec3 p) {
- vec3 projection = dot(p - a, n) * n;
- float dist = length((p - a) - projection);
-
- if (dot(projection, n) < 0.0) return -dist;
- return dist;
-}
-```
-
-Since all of our objects are spheres, we can just iterate through all of them and do this check.
-
## Appendix
##### LaTeX source for equations
@@ -535,10 +383,8 @@ The images for my custom LaTeX equations were created on [latexeditor.lagrida.co
```
[^matter-together]: Technically, it's more accurate to say "matter apart", since after the collapse matter is as close together as physically possible, and the nuclear forces keep everything in order but also separated. However, considering the intuitive approach I'm striving for, "matter together" is simpler to understand.
-[^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.
[^hitting-trains]: Of course, I'm asuming the trains are strong enough they won't break upon the collision.
[^angular-momentum]: Angular momentum is actually [defined using the cross product](https://en.wikipedia.org/wiki/Specific_angular_momentum#Definition)
[^light-has-no-mass]: Actually, light has no mass, so this version of the formula wouldn't work. You might think that makes no sense, since we cannot divide by zero, so the specific angular momentum shouldn't exist, but then with the cross product we find a value for it. You would be correct: Antonelli does some funky approximations, combining Newtonian physics with General theory of relativity, to make the formula that simple. Someone in physics will probably vomit looking at it, but for our purposes it's more than perfect.
+[^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.