How I made a 3D GAME in Desmos Graphing Calculator

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi a few months ago i created a video about my submission for the desmos art contest desmos plane a 3d game that runs entirely within desmos in this video i'll be tearing apart desmos planned allowing you my viewers to feast your eyes on its inners which i will document in excruciating detail so let's begin so first of all what is desmos plane anyway desmos plane is a game where you control a glider as it flies through a track your goal is to successfully navigate through the track without crashing into it and if you're up to the task to do so in as short a time as possible it has eight levels and i'd say the entire game is about 15 or 30 minutes long very roughly speaking if you want to try it out you can find the link in the description for the sake of maintaining all of our sanities i'm not going to attempt to make an expression by expression breakdown of desmos plane's code well unless you really want me to i will instead attempt to describe the overall process i used to make desmos playing starting with the rendering engine 3d rendering in desmos has been a hobby of mine for quite some time so the moment i saw the news of the desmos art contest i knew i had to make something 3d for it so i made a 3d rendering engine for desmos playing here's how it works the rendering engine starts out with a list of vertices and a list of vertex indices here are the vertices of a cube how do we actually create a cube-like shape with those vertices we have to connect them together into faces to be more specific we'll be connecting them together into triangular faces how do we do that well that's what the vertex indices are for each vertex has a position in the list called an index there's the first vertex the second vertex the third vertex etc the vertex index list tells us the indices of the vertices that make up the actual triangles on the cube the first triangles vertices indices are the first three vertex indices in the vertex index list the second triangle's vertices are defined by the next three indices and so on and so forth if vertices at positions one 3 and 2 make up a triangle then we would put 1 3 and 2 in the vertex index list of course this isn't enough information to actually render anything we know what triangles from which vertices we want to render we can't just render them to the screen because they're still 3d coordinates while the screen is 2d there are three things i had to worry about when making desmos played in regards to converting 3d chords to 2d coordinates translation rotation and projection translation is just moving around generally when you move around it appears that the rest of the universe is moving in the opposite direction so that's quite literally what i did in desmos plane if you move forward i just move all the 3d meshes backwards by subtracting your position from them rotation is well rotation i represented the rotation in a fairly simplified manner similar to many first person games where the camera is first rotated about the vertical axis the y-axis and deso's plane which resembles side-to-side rotation and then it's rotated in the side-to-side axis which is the x-axis at desmos plate which resembles up down rotation both of these transformations individually are analogous to a rotation in two dimensions which is described by this formula pause here if you want to use this formula yourself projection is the actual thing that converts the 3d coordinates to 2d coordinates and is the last step of the three some would say to use a projection matrix for this or something or the other but in my case simply taking the x and y values and dividing by the z value was good enough sorry folks this isn't opengl however even after all this we still don't have a proper 3d rendering engine in what order do we display the triangles do we go off of the order in the vertex index list that can't work consider this cube if the face is currently in front because last in the vertex index list and we suddenly flip the 180 degrees then that face is erroneously going to appear in front of the one closer to the viewer we can solve this issue by finding the distance to the center of each face to the camera and then sorting the faces based on those distances the first triangles are farthest away and the last triangles are closest so that the ladder is landed last in other words on top of the other ones where it's supposed to be and we're still not done yet let's go back to the cube example why do we even need to render these faces on the back anyway they aren't even going to be shown to the user in the cube is oriented this way desmos play needs as much performance as it can get and having all these extra phases isn't helping getting rid of these faces that face the wrong way is called backface culling fortunately a neat feature built into blender the software i use to make the desmos plane models will help us implement it blender enforces a certain winding order on polygons specifically all polygons in an explored blender mesh will be counterclockwise when facing the camera thus if we flip a polygon around so that it's not facing the camera it'll be clockwise what this means is that after projecting we simply need to filter out any clockwise polygons to call back faces there's an efficient formula for this in the stack overflow thread okay we're finally done in blending the renderer haha it's like there's still one last thing the colors this is mostly straightforward it's just a list of red green and blue values that vary between 0 and 255. each rgb triplet becomes the color of a single triangle alright but there's still a few things i haven't addressed in regards to the graphics that desmos playing the first is the lighting some faces are darker shades of color than the other the second is shadows some faces are included entirely and displayed in a much darker color than the others here's the thing none of this stuff was the book that in desmos i did have dynamic lighting at one point that was implemented in desmos but it was too slow to work with and given that this is desmos speed is something i have to fight for tooth and nail so i've instead opted to calculate lighting at compile time a process sometimes called baking a lining calculation is simple i take the normal of the face which is a unit vector perpendicular to it and i take the dot product of that with a direction vector of the incoming light the size of a dot product between two unit vectors is equal to the cosine of the angle between the two vectors thus well-aligned vectors have a dot product close to one while one's pointing in opposite directions of a dot product close to negative one we want normals pointing opposite the light directions to be bright so the closer the dot product is to negative one the brighter the light i use this process for both the stun and the multitude of other lights scattered throughout the scene the cast and shadows on the other hand were a heck of a lot more difficult and probably the technical achievement i am most proud of for this project see there's a problem with making casted shadows in desmos desmos polygons are only a single color i can't just draw part of a polygon light and part of a polygon dark because it's partially occluded by another it has to be entirely light or dark to get around this i did the only thing i could i split the polygons how well here's how i did it i first checked to see whether all vertices in the scene are included or not occluded vertices are blocked from the light by a triangle and thus or dark whereas non-included ones are not blocked by another triangle and thus are bright if all the vertices of a triangle are bright i assume that the entire triangle is bright colored in as such and carry on if all the vertices of a triangle are dark i assume that the entire triangle is dark colored as such and carry on interesting things happen when some vertices are bright and other vertices are dark there are two possible cases one bright and too dark or too bright and one dark either way two of the triangles edges will convert a dark vertex to a bright vertex what we're going to do now is examine those edges somewhere along each edge the triangle will switch from being dark to light or vice versa in the opposite direction we're going to find out where that switch occurs first cast array out of the middle of the edge let's say it turns out to not reach the light and is thus dark okay so the middle is dark and this vertex is dark and the light dark transition cannot occur in this interval leaving us with this interval let's check the middle of it to see whether it's light or dark let's say it's light now since we know that these two vertices are both light the transition cannot occur here and we've halfed our interval yet again if we repeat this process continually having the interval we will approach the point of transition between light and dark those who have done some programming may be aware that we have just done a binary search over the edge of the triangle let's repeat this process for the other light dark edge okay now we have these two points on the triangle identifying where it switches between light and dark we can use these to get a decent approximation of the shadow casted onto this triangle by splitting the triangle at the points at which it switches from dark to light we could accomplish this by subdividing the triangle like so coloring the regions as described here now the skeptical among you may have already identified a number of issues with this method how can we assume that the shadows will be like this when there could be an undetected light spot in the middle of a triangle or an undetected dark spot for that matter it'll miss all the vertices and thus the triangle will be assumed to be one solid color or what if there are multiple transitions between light and dark on the edge of a triangle this method will only detect up to a single one of them these are all valid observations and things i did indeed worry about while developing this algorithm however when all was said and done i realized that while this algorithm certainly wasn't perfect and had noticeable artifacts if i looked hard enough it was good enough that for the casual viewer it wouldn't matter all while being fast enough to run in real time in a game at the end all of graphics is nothing more than rough approximations of our reality approximations that must balance realism and speed fitted to their own specific purpose oh yeah speaking of shadow casting i recently created a much higher quality shadow caster it's a lot slower and thus impractical for something like desmos plane but it's almost pixel perfect check it out if you have the chance the most important part of this project however wasn't the shadow casting nor was it the collision detection nor the 3d rendering the most important part of this project was creating a streamlined workflow this is because it's a game meaning you'll have to rapidly iterate on it to produce interesting balanced fun to play levels and potentially fix bugs and a long drawn-out build process particularly one with manual steps is antithetical to this kind of rapid iteration i need to have a fast build process that compiles and loads desmos played with a single tap of a button now here's a little secret for how i made desmos planes workflow so fast i didn't make it in desmos yeah i lied to you this isn't a desmos game i made it an entirely different programming language i'm sorry i'm just messing with you this game does run entirely inside the desmos it is made entirely out of desmos expressions that you could type into desmos manually if you were a complete lunatic see the desmos expressions were desmos plane were not generated via desmos they were generated via a compiler that i made myself for this very project a compiler for a programming language called lispsmos lispsmos is put simply a programming language that i made that compiles to a desmos graph which i tailor made for desmos plane i have two versions of a newer version implemented in racket and an older version implemented in typescript the latter of which i used vertesma's plane it uses a lisp-like syntax for ease of implementation and extension or in other words because i was too lazy and inept to write a proper parser i won't get into the nitty-gritty details of how it works in this video but it has a number of advantages over regular desmos for one thing you can see a lot more on the screen at once there are more lines of code visible at once than there are in desmos expressions and perhaps most importantly i can define my own custom macros and whatnot i could expand to whatever i wanted listen to us macros i took great advantage of while writing the 500 lines of code that eventually became desmos playing i've embedded javascript i have 3d model importers i have macros that expanded macros and expanded yet even more macros allowed me to substitute whatever i want this feels proved to be an insanely valuable tool for creating desmos playing because i could express the decimals expressions i wanted with a single easy-to-read source of truth no manually copying and pasting hues of the data around or recruiting similar or distinct functions from scratch all of which i'd have to modify separately in case of an error does the experts say keep your code dry don't repeat yourself when you're writing code lists the most ensured that this would be the case oh by the way i'm currently working on a new language that supports several major improvements over list those stay tuned for that one okay but list dose wasn't the only powerful tool i took advantage of when making this project another was blender a free open source 3d graphics program with a whole host of features the one i was interested in were its 3d modeling and vertex coloring capabilities every 3d model in desmos plane was modeled and colored in blender this was another massive boost to my workflow because i can't imagine how frustrating it would have been to manually place down vertices and vertex indices to create meshes out of broad as most expressions seriously there are easily 5 000 triangles in this game to color in the triangle i used blender's vertex coloring feature i would then export everything as a dot ply file because blender can only export a single file at a time i made the plugin to export hundreds of them at once containing every single object in the scene you might also notice these boxes everywhere these are the hitboxes for each portion of the level see the world in deso's plane isn't just one mesh it's made of several meshes which are dynamically loaded in an outpace where the player is located i do this performance reasons because as you can imagine it's far faster to render three level segments at a time compared to the 30 or so that make up the entire game each box corresponds to the segment of the level when the players inside of a given box the corresponding level section is loaded practically everything that could be said to exist in the desmos plane world is driven by blender in this manner all these cubes are lights their size determines the brightness from their vertex colors that determine their light color these pairs of cubes determine the start point of each level along with the direction and speed at which the player moves when they are inserted into the level a few of the big hitbox cubes are also defined the zone in which you're considered to have entered a new level in other words if you're inside this cube the game knows that you've reached level 2. it might seem a bit odd to put all the level elements into blender like this but i found it to be far easier to tweak than if i did this all in desmos in a way it's like editing a scene visually kind of like when we're doing unity godot or other such game engine so yeah that was how i made desmos playing it was a long journey and probably the craziest project i made to date probably anyway check out the link in the description if you'd like to play it yourself and as always thanks for watching
Info
Channel: Radian628
Views: 294,559
Rating: undefined out of 5
Keywords:
Id: jEKsIB8EwVo
Channel Id: undefined
Length: 12min 15sec (735 seconds)
Published: Wed Sep 07 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.