5 ms·
Very cool, but I have a question. > This is done using WebGL, an API for drawing 3D graphics in a browser. You might think it's only designed to draw ordinary,
by ogogmad 5y ago
Very cool, but I have a question.
> This is done using WebGL, an API for drawing 3D graphics in a browser. You might think it's only designed to draw ordinary, Euclidean things, but it turns out it's perfectly suited to rendering this world as well. WebGL (and OpenGL) works with four-dimensional coordinates (x,y,z,w). Normally, you'll be advised to just set that w coordinate to 1 all the time. If you do that, the x, y and z coordinates will behave like ordinary 3-D geometry. I just ignored that rule and used the coordinates to represent points on the 3-sphere instead. It all works out. (You have to be a bit careful if you want to put textures on things without seeing seams between the triangles, but it can be done. The key is to make sure every flat surface is still a flat surface in 4-D.)
Are the 4D coordinates treated as ratios, so that (w,x,y,z) = (tw, tx, ty, tz)? Because then that would express RP^3 instead of S^3, i.e. projective 3-space, instead of the 3-sphere. Equivalently, this produces a model of 3D elliptic geometry, instead of 3D spherical geometry. My doubts are because 3D computer graphics is known to use homogeneous coordinates, which results in a model of projective 3-space or elliptic 3-space.
S^3 can be coordinatised using elements of R^4 of unit length, which might have been done here.
- Asooka 5y agoThe w coordinate is there to aid the perspective transform and translations. Because in homogeneous coordinates everything becomes a matrix multiplication. At the end, before rasterisation, the coordinates are normalised by dividing by w. Yes, you can use it for whatever else you want, GPUs are just vector processors, as long as you keep in mind how the rasterisation step will happen.
- ogogmad 5y agoThanks. I'm aware of all those uses. But that strongly suggests that he's constructed a simulation of projective / elliptic 3-space, not spherical 3-space. The image on the screen is a perspective projection thereof. Additionally: To clarify my understanding of projective vs elliptic geometry, because I keep conflating them: Projective space is a topological space, while elliptic space is projective space endowed with a certain metric, turning it into a metric space. Additionally, every elliptic isometry is a projective symmetry, while the other way round isn't true. On a purely topological level, there's no difference between elliptic geometry and projective geometry.
- joppy 5y agoAs long as you normalise by only multiplying/dividing by positive numbers rather than any nonzero number, you’re really working in S^3.
- falsifian 5y agoThe 4D coordinates are almost treated as ratios. (x,y,z,w) = (tx,ty,tz,tw) when t is positive, but if t is negative it's a different point. This happens to work with (Open/Web)GL. Here's my understanding of why. Say you tell WebGL to draw a triangle with points at clip space coordinates (i.e. after all the transforming is done) (1,0,0,1), (0,1,0,1), (0,0,0,1). If you multiply all those by a positive number, e.g. (10, 0, 0, 10), (0, 10, 0, 10), (0, 0, 0, 10), you get the same triangle. But if you multiply by a negative number, they will not be drawn at all: (-1, 0, 0, -1), (0, -1, 0, -1), (0, 0, 0, -1) is not drawn. I think this is because of the rules for clipping: only points where -w <= x,y,z <= w survive the clipping step. If w is negative, that's impossible. Related: my code draws the universe twice on each frame. First I draw things that are more than halfway around the sphere from you, and then I reset the z buffer and draw things that are closer to you. https://git.sr.ht/~falsifian/s3d/tree/main/item/src/S3D/Draw.idr#L22 https://git.sr.ht/~falsifian/s3d/tree/main/item/src/S3D/Draw...
- falsifian 5y agoAnother thing maybe worth mentioning: the magnitudes matter when GL is doing interpolation, which is especially noticeable when there are textures. That is, if you scale just one of the three points of the triangle, e.g. (1, 0, 0, 1), (0, 1, 0, 1), (0, 0, 0, 1000), then while the triangle will appear in the same place as before, interpolation (e.g. deciding which part of the texture to draw in each pixel of the triangle) changes. The current version of the demo doesn't have any textures but that's mostly laziness on my part. For a while I gave the rooms "ceilings" which were each a checkerboard-pattern square, which forced me to figure out how to get the interpolation thing right. So I can confirm it can be done. But I dropped the ceilings because they just got in the way.