For the sake of the question, imagine that I’m making a game engine from scratch by one of the popular programming languages and I would like to put an interactable crate in my game. How does the game know what a crate is? I’m thinking like they create a crate in one of the rendering software, but how do they translate that to a game? Do they do something like
`define “crate” crate.stl`
then refer to it only as “crate” to give it animation, physics and lighting properties by extra code, or does it work completely differently?
A follow up question, I want to give velocity to my crate when it’s propelled by the player. Let’s say I tell it moves on x axis by “5” when “interact” happens, how is x axis or velocity defined?
In: Technology
It’s basically just a list of 3D coordinates that defines the geometry of the crate, along with a list of integers that tells you in which order you need to connect the 3D coordinates. A 1x1x1 box would just look like:
(0,0,0),(1,0,0),(1,1,0),(0,1,0),(0,0,1),(1,0,1),(1,1,1),(0,1,1)
and then the indices of those coordinates that tells the computer which points to connect. The most basic style is to give the computer a list of triangles to render. For example, to render one side of the box, you’d need to render two triangles, and each would use 3 of the 4 coordinates for the corners of the box:
0,1,2 (first triangle) 1,2,3 (second triangle).
To add textures or colors to the box, you’d include more coordinates (0,0,0,0) instead of (0,0,0) where the additional coordinate tells you what part of the texture image aligns with that corner of the box.
The question you’re asking is really a question of data structures, so I’m gonna answer that. I don’t mean it as an insult, but you’re working at the Computer Science 101 level, and you’re not ready to think about making a videogame engine.
You’ll need some kind of array to represent the entirety of the map of your game, and it exists so you can reference it as a coordinate system for the different pieces of your game. A chess board, for example, could be an 8×8 array. More complicated games need a much more complicated system for defining their coordinate system.
Once you have your grid system laid out, putting an object in that system means assigning it a location and dimensions based on that location… for example a 1×1 square located at (0,0).
You’re going to have to ask more specific questions if you want more specific answers.
There are systems programmed in the engine to handle each thing, lets simplify it to only rendering and physics.
The crate would have some data in a model file which would tell the renderer how to make the visual model of it using polygons (mostly triangles), with different locations, sizes and orientations. It doesn’t matter exactly how this is stored (vertices and indexes etc)
Using the positions and strengths of lights in the scene, and the angle between faces and light sources, the colour for each pixel on the screen is calculated in the graphics pipeline
The physics engine would use simple 3d geometry to have a collision box or hitbox which would be used to calculate when objects overlap and make an appropriate response to mimic the effect of solid objects
The most basic hitbox is a sphere, with position and radius, then there’s an axis aligned cuboid, with position, x y and z dimensions, and then more complex shapes like orientable boxes, capsules etc can be written
Physics objects have the same mass, velocities, forces that they do in real life (inverse mass is a thing but not important), and since we have known equations of motion (Force = Mass x Acceleration, Distance = Speed x Time etc) it is relatively straight forward to simulate motion like this, and then just update the positions of the objects so the renderer moves the visuals appropriately
Just to expand on what others are saying: the way a conventional game engine renders stuff on screen (I.e. rasterisation) fairly closely mimics the way you would draw something on paper.
First, you have the object you want to draw. Say, a figurine. As others have said, this figurine is defined as a set of triangles that, when slotted together, form the object. These triangles are defined as offsets from the “origin” of the model, for example the centre of the figurine’s base.
Next, you have to place the figurine in your 3D scene, on top of a desk for example. You translate those offsets to be relative to your scene, e.g. placing that collection of triangles on top of a table. This is the “model” or “world” matrix.
Then, you have to express where those triangles sit in relation to the camera or viewpoint. Is the figurine in the centre of the frame, off to one side in the background etc. This is the “view” matrix.
Finally, you have to translate those 3D coordinates in your world to 2D coordinates on a page. I.e. does the figurine appear on the top left of your page, the centre, does it take up most of the page or is it a tiny detail etc. This is the “projection” matrix.
You then combine all three into a “model view projection matrix” which is a matrix that when you take your figurine’s 3D triangles and multiply them by that matrix, you get a set of 2D coordinates where 0,0 is the centre of your “page”.
Now the renderer draws out the triangles and “colours them in” to draw a single frame of your game. Obviously there is a LOT that goes into the colouring in phase, but outside the scope of this example.
Essentially, there is a data structure that is used In many engines called a scene graph.
This is a way to structure various objects in a hierarchy that makes it easier to manipulate them.
For example your box could be a node in the scene graph that has various attributes applied to it (eg moving). If there are things in the box, they would be children of that box node, so when you apply a transformation (eg move 5 units in the X direction) that transform is applied to all the children of that node.
This structure also helps when you have groups of objects that move relatively to each other but also need to move together. For example if you have a character with a bird flying around him, you don’t need to worry about what global space coordinates it needs to orbit, you tell it to orbit the character and when the character moves that orbit is also moved without you needing to know where the center of that orbit is in the global coordinate space.
There are many tricks you can do to speed up things, for example your box textures or other data it has can be separated, so that of you have say 10 boxes, they reference that same data.
Obviously when you have very large and complex scenes, there are also other tricks that are used to reduce what is displayed etc. You can also have things like bounding boxes attached to various nodes for collision detection etc.
Modern game engines are insanely complicated and there are many tricks used to improve performance and memory utilisation, so this is a very basic description, but the main idea is that it provides a hierarchy for your in world objects that aims to optimize various typical operations you might want to do to them (moving, rotating, changing size, detecting collisions etc.)
Imagine you have a really big 2D graph (easier to visualize). You can give something a position on the graph using coordinates like (2,4). You can also “move” from a given position, by saying, from (2,4) move (+3,-5), and you get a new position. This is one of the basic concepts in linear algebra (vectors). You can also create more complex objects, like a triangle, that takes up more space by saying that the object has multiple vertices, and then connecting the them with edges. You can apply this concept to 3D spaces too. Put all of this together and you have the building blocks needed to create objects in 3D spaces, move them, detect collisions, etc. (not really an el5 answer, also not really an el5 question lol)
First off, as others have explained, 3D objects are primarily a collection of points, and how the points link together. The simplest object you can make, and the one that ultimately makes up all other objects is the triangle.
To make a rriangle, you need to define 3 points. Lets call them A,B and C. Now aside from the points, you also need to define the edges, which you can do in one go as a collection of points [A,B,C]. (Imagine drawing lines from A-B, B-C and C-D.
As an extension of thia, to make a square, you only need 4 points, but still need to make it out of triangles, of which you need 2. But triangles can share edges, so you can have a square using 4 points, ABCD, and two triangles, ABC and BCD.
All of 5his is just a collection of numbers in some agreed upon format. Just a way of storing structured data.
Now, this is loaded into memory, and game engines differ. But think of this 3D object that you load from a file as a template, a collection of points and triangles (vertices actually). You use it to create an instance of that object in the game engine.
In the game engine, and the programming part in general, we use object oriented programming to make things easy to deal with. In computer memory, they are all just blocks of memory allocated for each object, which the programming language manages for us, but in the programming language we may have a “class” that describes properties of the object.
We as programmers (someone down the line) need to create that class. An Objecr class might look like
“`
class Object
{
float X;
float Y;
float Z;
float ScaleX;
float ScaleY;
float ScaleZ;
float RotateX;
float RotateY;
float RotateZ;
VertexList Vertices;
}
“`
Basically contains the information needed on positioning something in a 3D space. The neat part about this is you can use the Object class to create multiple Objects in memory. We can give each object different names so we know what it is . Like crate1, crate2, MaxPayne, etc.
The VertexList can also point to just one copy of a crate, so you can have multiple crate objecrs that reuse a set of vertices.
So when a 3D model is loaded into memory, it has a bunch of points that are “fixed” relative to some point of origin. We call this “object space”
When the game engine draws stuff, it takes a copy of these vertices and applies transformations to it based on the object properties.
For example, a triangle might be defined in object space as ((0,0), (0,1), (1,1)) and it stays that way in the object. But when drawn to screen they get copied and adjusted based on where we want to draw it. So an crate with X,Y,Z set to 10,10,10 will appear at a different location than a crate at 20,20,20, but they still use the same crate vertices to draw from.
Then when the game engine needs to draw stuff it looks at this list of objects and has the information of
* what to draw (list of vertices)
* where and hiw to draw it (object)
These are sent as commands to the Graphics card (GPU) and updated each frame.
The rest of the game engine and the game itself is about interacting with these objects via their properties.
Need to check if a crate hit another object? You check its position, do some math, and update the crate or thw other object, or both.
After all the calculations are done (and they must be done in less than the time it takes for a frame, which is for our purposes, 1/60th of a second) all the objects on screen are rendered by the game engine all over again.
Of course this is a huge oversimplification and there are so many optimizations and things going on to make things faster and more efficient.
It would be an instance of a structure/class/object. In a voxel based it would have inherent position, otherwise it would have xyz position. Whatever other bits it has depends on the game. Probably xyz of momentum, hp and hp Max, pointer to a model and a while bunch of other things.
There would be a loop that goes through all active objects and moves them. They would be added to that list if interacted with.
vec3 velocity; // or float vx,vy,vz;
//X axis is just inherently 3d when you write physics and vertex shaders
It’s all just pretend. The computer never has any idea what a 3D object is. There are 3 main parts:
First the programmer just defines a group of data that will represent 3D objects. That data will usually at the very least have 3 numbers, which the programmer decides will represent XYZ position coordinates, and maybe some other numbers that will represent rotation, size, velocity, etc. There will also be a way to load a list of 3d coordinates (just more arbitrary numbers) from the 3D model file. To the computer it’s all just a list of numbers, so it’s loaded and stored just like any other data.
Next is the “editor.” This could be a full 3D level editor that outputs a file our game can read, or it could be just typing a text file by hand that says something like `[crate 0,3,4] [player 8,9,2]….`, specifying which objects to spawn at which coordinate and whatever other data we need. It really doesn’t matter, since we’re the programmer we get to define how our game reads the data, so we can make our game read whatever random data we want, how we want. Maybe we also include the file path to the 3D model in that level file, or maybe we program our game where if it sees `[crate X,Y,Z]` it just automatically looks for `crate.stl` in a specific folder. It’s all up to us.
This is still all just random data to the computer, nothing but a massive list of numbers stored in memory. In order to display it to the screen, we tell the computer to go through all of those points we loaded from the 3D file, calculate `point + object_position` and for every 3 points draw a triangle. In order to get the 3D effect, we do some math on those points to “project,” them into the screen, which is basically the same thing you do by hand when you draw a “3D cube,” on a piece of paper. At the end of the day, we’re just drawing 2D shapes on a monitor. We then write a “shader,” which is a small bit of code that tells the computer how to color each pixel of that triangle, which usually uses some 3D math to calculate lighting and such.
We tell the computer to do the previous step for every object, 60+ times a second. If we include a piece of code that says “every frame, take the position and add the object’s velocity to it,” then the object will be automatically drawn at the new position on the next frame since it’s recalculating every frame anyways.
Sorry if this is an overload. 3D graphics is a LOT of information, but each step is relatively simple to understand, so if you’d like me to break down a specific step further just let me know (I’ve worked as both a 3D graphics dev and a 3rd grade teacher, so I should be able to answer any question you have).
Latest Answers