It is an entirely valid question to ask what this project really is about. The bottom line, being as simple as I possibly can be, is that it's a 3D rendering engine, that uses SVG to draw to the screen. This tool does not use the <canvas> and <img> tags anywhere in its code, nor does it use CSS.
You might think that this means that this is a software like Blender, or Unity, (both of which are, to some capacity, 3D engines as well), but its main purposes differ. That is because both of these tools are used for rendering/modelling 3D graphics, but they do not implement the graphics pipeline itself, rather, they leave this to an outside library, like OpenGL or Vulkan. Which is by all means the right thing to do! You'll see that meshes rendered by this method are no better
The graphics pipeline is all the math and pre-processation your computer does in the background before drawing the graphics of, for instance, this sphere.
There are some steps to it. I'll keep them as simple and concise as possible
First, you need to send the data of the cow itself. This is sent through a list of vertices [V1,V2,V3...] that defines triangle in a 3d space, and a list of indices
[I1,I2,I3...] that describes how each triangle connects to one another. Together with those, you send matrices describing the transformations you will apply to these vertices (this is called the Model matrix),
and other relevant data for the renderer, like the angle and position at which your camera is (View Matrix) and the perspective you're using (Projection) matrix. In this step, you'll typically compute (or just import them from whatever drawing software the 3D artist were using) normals, which indicate the direction each vertex is facing. This is useful for collisions and lighting.
Before transforming into the 4D clip space, we work with what we call the World Space (which is where the mesh is in reality), and perform all calculations we need there. This would be things such as collision, lighting, shading, etc. If you ignore the raycasting aspect of it, the lighting process is surprisingly simple: you treat light as points in space, and compute how intense it is according to its distance from a point (a flashlight turned on in Brazil won't shine a light in someone in Japan), and the angle at which it hits a vertex (the sun casts light on your roof but not inside your room, even though they are both in similar distances from it - that is because it faces away from the sun).
Then, you apply transformations to turn your vertices that are defined on their own local space to take into account your camera, and transformations (like rotation, scaling and translation) applied to the object in question.
One key difference to be noted is that these transformations consider your vertices [Vx,Vy,Vz] as a 4D [Vx,Vy,Vz,1]. This is because when applying the transformations (which are done through matrix multiplication),
this fourth coordinate will hold how "big" this vertex will be relative to your camera. This is called Clip Space, and it's what makes, for instance, the sun look small in a 3D engine (because it's really far away!)
We exit Clip Space by dividing the x,y,z components by the fourth, w component and enter screen space. In it, we usually would have a rasterizer, that transforms these vertices into pixels, interpolates their colors, and draws them on the screen. But this is not what this engine does.
Why? Because we have no pixels to work with.
All our drawing is done by using the native HTML element, <svg>, which stands for Scalable Vector Graphics. It is great at drawing lines because that's what it's made for: you feed it points, and it will draw a path that goes through them. This comes at the tradeoff that we don't have the power
to manipulate pixels anymore, nor to (efficiently) interpolate colors. Another problem is that we constantly have to fight the DOM: when we create an element, there is lots of calculations done over it besides just rendering it to the screen. 3D animations means that we have to erase and rewrite thousands of DOM elements every frame which is, of course, very, very expensive. This is the main limitation of our 3D engine.
Drawing wireframe models (that is, just the outline of them) can and is done very simply. Since svg's path tag allows for as many different points as possible, we just write it all to a single, huge path. This makes wireframe drawing far faster.
When it comes to coloring and shading models, this becomes more complicated. Normally, we'd do something called Barycentric Interpolation, where we give a color to each vertex of a triangle and create a gradient-like like for the face. This is not to say it's impossible to do this in svg - LinearGradient is a tag that (sort-of) solves this problem with
some tricky math, but not only it's an expensive element for the DOM to render, but it would make our svg string 3 to 4 times larger than usual. This means we have to use flat shading (coloring the face as the mean of each vertex's color).
I started developing this project to submit it to a challenge where people were asked to make a page that did not use CSS. In developing it, I added some other personal constraints to make my life harder (otherwise, using canvas would trivializer the challenge),
and ended up completely forgetting about it and missing the deadline.
Ultimately this project's main purpose is to have fun. I certainly had so when developing it, and I hope you do too using it!