FOUR DIMENSIONAL rendering engine in WebGL!
Note: Open the repl in a new tab, it won't work if you don't
Wait, how does that even work?
If you're completely unfamiliar with this concept, this is a very hasty introduction so I'd suggest doing some outside research. (Check out this video for starters.)
First off, by "fourth dimension" I don't mean time — I mean an imaginary, fourth spatial dimension, another direction to move in. We don't have this in our universe (we can only move up/down, left/right, forward/back), but computers don't care about reality and can simulate a fourth dimension just fine. All it means is adding a fourth coordinate to a point: instead of x,y and z, we now have x, y, z, and w.
Of course, in practice things get a bit more complex. Since we don't actually have a fourth dimension in our universe, how do you display a 4 dimensional object? The simplest way (conceptually that is) is to use slices; this is the method that I've taken with this renderer.
To explain, let's imagine you're a 2D hand-drawn stick figure trying to view a 3d orange. Since you're 2D, all you can see is what's on your piece of paper (you can't look "out" of the paper into the 3D world). So how do you view the orange? Well, cut up the orange horizontally into a bunch of circular slices, and then you can place each slice on the paper, one at a time, to "construct" an image of the orange in your mind.
This is exactly what I've done here, except instead of cutting a 3d object up into 2d slices I've cut 4d objects up into 3d slices. Then, you can view each 3d slice of the 4d object just like a normal 3d rendering.
Stop babbling I want to see in 4D
Okay okay, here's how you can use the repl:
- You can move around the little red cube with WASD and rotate the camera with Q/E
- Use J/K to move through the 4th dimension; this is effectively moving where you are "slicing" the 4D scene
The loaded scene contains a bunch of randomly-generated 4D rocks in a garden. The garden is either sandy or grassy, depending on where you are in 4D space. (In our world, this would be like having a garden split in half with one side being grass and the other side being sand.) Notice how the rocks morph around (and even appear to "float" in the air sometimes)? These rocks are in fact completely still! This is actually just a product of seeing different "slices" of a static 4D object. Back to our stick figure with the orange: by moving the slicing position, you'd see the orange's circular slice appear to "grow" and "shrink". This is best represented in a picture:
Notice how when the sphere is sliced in different places, the dotted circular slices are different sizes. This is exactly what is happening in the 4D rendering, except it's 3D slices of 4D objects appearing to change size.
Why is it all pixelated though?
This brings me to my conclusion, and the reason that I'm posting this in the first place. The renderer uses raymarching, which is sort of like raycasting's big brother if you're familiar with such a system. Basically, the renderer determines what color to render at each pixel by sending out a "laser beam" which hits the object and finds the color. Unfortunately, as it turns out this system really can't perform well on any significant scale since it has to do too much checking for intersection. This led me to lower the pixel count, so it would not have to send out as many laser beams — but even still, anything over about 20 objects is basically unusable. There might be some kind of hidden optimization possible, but I've struggled to find anything as the system is fairly barebones as it is.
So, sadly, after finally getting the renderer to work I'm going to have to abandon it since it's just not performant enough to be usable.
Wait, usable for what?
You'll just have to wait until I make a tetrahedral renderer to show you :)
Hope you enjoy!
@SilvermoonCat Yeah, that's the performance issue I mentioned in the description. Some people with really good GPUs have gotten it at full 60fps, but for most it's about 20-30fps and for some it's really really low (0-6fps).
But don't be discouraged, the tetrahedral renderer won't suffer from the same issues!
Higher dimensions are awesome. Do you mathematically convert a slice of a 4d object into a 3d object before rendering?
@TheTranscendent Thanks! No, I'm using raymarching. Basically, the "laser beams" (see talk post) are sent out in whichever way the camera is facing, and not moving at all in the fourth dimension. This ensures we see only the 3D slice of the fourth dimension at the position we are at (since the beams don't move "forward" or "backward" in the fourth dimension), and from that point the raymarching is pretty standard.
I think what you're thinking of is the technique that's going to be used in the tetrahedral renderer, rasterization.
@Baconman321 First off, throw quaternions out of your head. They operate in a 4-space, but it's a completely unrelated 4-space — they just use an abstract notion of a fourth component to accurately represent a rotation in 3D. (Technically, quaternions are just overcomplicated rotors, and rotors operate in 3-space.)
I'm not exactly sure what you mean by the first sentence, but (assuming you've watched the video at the start of the description) lemme try to elaborate.
If you were a 2D stick figure and could only move left/right and forward/backward, you couldn't see "up". It just wouldn't exist for you — after all, pencil marks on paper can't magically jump out of the paper. This is like us in our 3D universe: we can't move in a fourth dimension since it simply doesn't exist for us. We can move up/down, left/right, forward/backward, but that's it, there's no other way to move.
Let's go back to the 2D stick figure now. Imagine we gave this stick figure the ability to magically "jump out of the paper" to however high up it wants to go. Now remember: the stick figure can't actually see up or down, it still can only see left/right and forward/backward, but now it can move up and down. This is the part that is a little hard to grasp at first — being able to move in a direction without being able to see in that direction. Okay, so what exactly would the stick figure see? Well, let's say they're on a desk, and there's a book to the right of the stick figure. If they were aligned with the book (up and down, that is), then they'd see it since it's in their "plane of view" (left/right or forward/backward). But as soon as they decide to move above or below the book, it would vanish because now it's not in the same "plane of view" as them. The stick figure could only see out to the left, right, forward, or backward, but the book is now below them! Now, imagine there's an object that's a circle on the bottom and a square on the top sitting on the desk. (Like a weird cylinder where one end is a square). When the stick figure is in line with the bottom of the object, it would see a circle. But as it moves higher, it would see a square! (Remember: the stick figure can only see what is in line with its height.) So, as the stick figure moves up and down, objects would appear to appear, vanish, or even change shape!
Now, this is exactly what's happening here, except we are 3D and we are in a 4D space. We can only see what's in line with us in the fourth direction — we can't actually see into the fourth dimension. The fourth dimension is like height in our stick figure analogy — we will only see a "slice" of the actual space, and as we move through 4D the slice will change. So, when you see objects that are appearing to "morph" as you move through 4D, that's because they are just different shapes at different points in the fourth dimension.
I hope this helps any, if you have any more questions please ask!
@fuzzyastrocat Watching the video plus ur explanation helps. The 4D plane is arranged in a way in which we can only see it if our plane of vision intersects with it.
But what would it be used for? What is the point of this? It would make gaming much more complex and would be quite confusing...
Yeah, quaternions just help with rotations in a way that won't come across the gimbal lock problem.
@Baconman321 What is the point of this? Fun! I mean, there's not a whole lot of applicability here, it's just a fun mechanic for games and such and can make mesmerizing graphics.
One application that I have heard of though is that some crystal structures can be described more cleanly in higher dimensional space. I.e. all crystals of type ____ can be described as the same shape just rotated through, say, the fourth dimension. I don't really know a whole lot more about this, but it's interesting to see that higher dimensionality can have some practical value.
Hi, you seem to know a thing or two about ray casting, do you happen to know the algorithm for 3d intersections between a line segment and plane as well as the intersection location? I'm looking for the concepts behind the algorithm rather than just being fed code.
@realTronsi Are you familiar with vector representations of surfaces? If so, try substituting the vector parametric form of the line into the vector parametric form (the one that uses the plane's normal, specifically) of the plane. Then you can plug in the solution back into the line equation to get the intersection point.
If not, try checking out these two pages, I think they give a pretty good overview of how the vector representations work: https://tutorial.math.lamar.edu/classes/calciii/eqnsoflines.aspx, https://tutorial.math.lamar.edu/classes/calciii/eqnsofplanes.aspx
I don't know how much experience you've had with this kind of thing, so if you're confused I can try to give more background.
you need to put a warning to only use this on advanced computers or else, my computer froze for 10 minutes. DON'T USE THIS ON LOWER END COMPUTERS
@TimothyClark222 Froze to 10 minutes? That's certainly a long amount of time, I would've put a warning but I did not think that such a performance drag would happen at all. (And it's not on advanced computers only, I've tried it on low-end computers — as have some others here — and although the performance is really bad it hasn't actually lagged the computer for significant periods of time.)
@notTussiez Thank you!
Guess what: I have! And actually, that example isn't much faster. For one, it has less objects in the scene, so it doesn't have to do as much computation. And secondly, try opening it in fullscreen, you'll see a significant performance drop. That's because raymarching is heavily dependent on the resolution of rendering, so it's fine rendering a really small picture but as soon as you try to make it render something larger it drags significantly. (The implementation of the raymarching algorithm is actually basically the same on both these projects, just that this one also has a system for determining position, color, rotation, etc depending on the object's metatdata.)
Really, the only way to improve performance is to not use raymarching, which is why I'm working on another renderer. :)