3D Graphics: A Beginners Guide
Nowadays 3D Computer graphics, or CG, are everywhere. From video games to medical applications.
The film industry is dominated by computers, and it’s not just sci-fi and animation. While filming the Irishman, Martin Scorsese used computer effects to de-age actors Robert De Niro, Joe Pesci, and Al Pacino.
It’s kind of crazy when you realize that the first feature film to incorporate computer generated imagery was Westworld, starring Yul Brynner and James Brolin. That was in 1973, more than 50 years ago!
Today, we have devices like the Meta Quest 3 and the Apple Vision Pro, which blend digital content with your physical space.
With all of this, it’s clear that 3D computer graphics have become an integral component of our everyday lives. But, how are computer graphics created?
In this article I want to give a brief overview of how computers generate the images we see on the screen. This isn’t a deep technical analysis of all the hardware and software processes involved in CG, but rather a more casual introduction for beginners.
The Pipeline
The process usually begins with an artist or designer using 3D modeling software like Maya, Cinema4D, or Blender, just to name a few.
Artists usually start off with a simple shape like a box or a sphere and then use different tools to modify this geometry. The following image shows a monkey head model created using the free and open source software Blender.
If we inspect the model closer, we can see that it’s made up of a collection of points joined together with simple geometries. This structure of joined points is known as a Mesh.
Each individual point is known as a vertex. A vertex is a point in space that has coordinates x, y, and z which determine its position in the 3D world.
So, meshes are made up of vertices and vertices are made up of coordinate values. But how do we go from three numerical values to something on the screen? A graphics pipeline is a sequence of stages that transform data from a mathematical representation to something on a screen.
In essence, all 3D objects are just data. Data can live in a 3D space, however, our screen is not 3D. We need to take vertices in 3D space through a series of stages in order to transform them to a 2D space.
Let’s start with the first stage: the Vertex Shader.
The Vertex Shader
Imagine we have a simple cube. This cube geometry is defined as a list of 8 vertices.
The vertex shader first transforms these vertices from a space where they are relative to their own origin, to a new space where everything is in relation to a camera’s position and orientation.
Finally, we take vertices from a 3D coordinate system into a 2D plane by using perspective projection. Projection creates the illusion of depth by scaling an object’s coordinates based on their distance from the camera. This simulates how objects appear smaller as they move away from the viewer.
Now that our vertices have been transformed to a 2D space, it’s time for the second stage: the primitive assembly.
The Primitive Assembly
Once vertices have been transformed, it’s time for the primitive assembly.
In this stage, vertices are connected through geometric primitives. We can choose to use lines, points, or triangles. Most modern graphics hardware are optimized to process triangles efficiently, that is why we usually choose them over lines and points.
The primitive assembly lays the groundwork for the next step, which is rasterization.
Rasterization
We now have geometry made up of 3 dimensional vertices projected onto a 2D screen.
The rasterization step determines which pixels are inside the triangle. It breaks the shape into small fragments or pixels.
Rasterization not only determines which pixels are inside the shape, but also improves performance by discarding triangles which are not visible or occluded. This is known as Culling.
Culling determines which triangles are facing away from the camera, are outside of the camera’s view, or simply hidden by another object. In this case the triangle gets discarded and the computational load on the GPU (Graphical Processing Unit ) is reduce.
The Fragment Shader
The next stage in the pipeline is known as the fragment shader.
After rasterization, the triangle is broken into pixel fragments. These individual pixel fragments are then processed by the fragment shader.
In this step we determine a color for each of the pixels that belong to the triangle. We do this by taking into account the material properties of the object, textures, and light sources in the scene.
with all of these information, we perform some calculations that determine the final color of the fragment.
Framebuffer
Finally, all of the shaded fragments are copied to the framebuffer, which is basically the image displayed on the screen.
You can think of the framebuffer as a canvas where everything gets stored before being displayed on the screen.
This is the last step in the graphics pipeline.
Final Considerations
We have followed our vertex data through the different stages of a graphics pipeline. This is a general overview of a typical graphics pipeline. Note that there may be different pipelines, which have additional steps that we ignored.
One thing that I want to mention before we go, is certain changes in graphics pipeline through the years.
Earlier versions of graphics libraries offered “fixed” pipeline. This means that the process had predefined stages and operations. Specifically, the vertex and fragment shaders. Developers had limited control over how these specific stages behaved.
With older pipelines, we would simply define the vertex data, material data, and lighting. Then, we would send this data to the GPU and we’d get a result. This was easier for beginners, but provided little room for modification and customization. For example, the lighting model used could not be changed.
In modern graphics libraries, “fixed” pipelines are deprecated in favor of “programmable” pipelines. Modern pipelines provide greater flexibility and control over the rendering process. However, you must provide the code for the vertex and fragment shader yourself. This means more control for the developer, but an additional layer of difficulty for beginners.
Shader programs are written in a C style language called GLSL. Shader programs run on the GPU, which is different from how programs run on the CPU. The CPU executes tasks sequentially, while the GPU executes tasks in parallel.
The fact is that this extra layer is worth it! We can achieve great results with these new pipelines. There is also a thriving community of creative individuals that are constantly pushing this technology even further.
I hope that this quick introduction gives you a clear understanding of the process required to create computer graphics, specially 3D graphics. Perhaps this brief introduction piques your curiosity a little bit and you might be motivated to learn more about computer graphics.