How do Video Game Graphics Work?

How do Video Game Graphics Work?

Branch Education

0:00 Video games have spectacular graphics,

0:02 capable of transporting you to incredibly detailed cities,

0:06 heart-racing battlegrounds, magical worlds, and breathtaking environments.

0:12 While this may look like an old western

0:15 train station and locomotive from Red Dead Redemption 2,

0:18 it’s actually composed of 2.1 million vertices assembled into 3.5 million

0:25 triangles with 976 colors and textures assigned to the various surfaces,

0:31 all with a virtual sun illuminating the scene below.

0:35 But perhaps the most impressive fact is that these vertices, textures,

0:40 and lights are entirely composed of ones and zeroes that’s continuously

0:46 being processed inside your computer’s graphics card or a video game console.

0:51 So then, how does your computer take billions of ones

0:56 and zeroes and turn it into realistic 3D graphics?

1:01 Well, let’s jump right in.

1:06 The video game graphics rendering pipeline has three key steps:

1:15 Vertex Shading, Rasterization, and Fragment Shading.

1:18 While additional steps are used in many modern video games,

1:22 these three core steps have been used for decades

1:26 in thousands of video games for both computers and consoles

1:29 and are still the backbone of the video game

1:32 graphics algorithm for pretty much every game you play.

1:36 Let’s begin with the first step called vertex shading.

1:39 The basic idea in this step is to take all

1:43 the objects’ geometries and meshes in a 3D space and use

1:47 the field of view of the camera to calculate where

1:51 each object falls in a 2D window called the view screen,

1:54 which is the 2D image that’s sent to the display.

1:58 In this train station scene, there are 1,100 different models and the camera’s

2:04 field of view sections off what the player sees,

2:07 reducing the number of objects that need to be rendered to 600.

2:12 Let’s focus on the locomotive as an example.

2:15 Although this engine has rounded surfaces and some rather complex shapes,

2:20 it’s actually assembled from 762 thousand

2:23 flat triangles using 382 thousand vertices

2:27 and 9 different materials or colors applied to the surfaces of the triangles.

2:34 Conceptually, the entire train is moved

2:37 as one piece onto the viewscreen, but actually,

2:40 each of the train’s hundreds of thousands of vertices are moved one at a time.

2:46 So, let’s focus on a single vertex.

2:48 The process of moving a vertex, and by extension, the triangles and the train,

2:54 from a 3D world onto a 2D view screen is done using 3 transformations.

2:59 First moving a vertex from model space to world space,

3:04 then from world space to camera space,

3:07 and finally from the perspective field of view onto the view screen.

3:13 To perform this transformation we use the X,Y,

3:16 and Z coordinates of that vertex in modeling space, then the position, scale,

3:21 and rotation of the model in world space,

3:24 and finally the coordinates and rotation of the camera and its field of view.

3:30 We plug all these numbers into different transformation

3:33 matrices and multiply them together resulting in the X

3:36 and Y values of the vertex on the view screen as well as a Z value or depth,

3:43 which we’ll use later to determine object blocking.

3:46 After three vertices of the train are transformed using similar matrix math,

3:50 we get a single triangle moved onto the view screen.

3:54 Then the rest of the 382 thousand vertices

3:58 of the train and the 2.1 million vertices of all the 600 objects in the camera’s

4:04 field of view undergo a similar set of transformations,

4:09 thereby moving all 3.5 million triangles onto a 2D viewscreen.

4:15 This is an incredible amount of matrix math,

4:18 but GPUs in graphics cards and video

4:20 game consoles are designed to be triangle mesh

4:24 rendering monsters and thus have evolved over decades

4:28 to handle millions of triangles every few milliseconds.

4:32 For example, this GPU has 10,000ish cores designed to efficiently execute

4:39 up to 35 trillion operations of 32-bit multiplication and addition every second,

4:46 and, by distributing the vertex co-ordinates

4:49 and transformation data among each of the cores,

4:53 the GPU can easily render the scene resulting in 120 or more frames a second.

5:01 Now that we have all the vertices moved onto a 2D plane,

5:05 the next step is to use the 3 vertices of a single triangle

5:09 and figure out which specific pixels

5:11 on your display are covered by that triangle.

5:15 This process is called rasterization.

5:17 A 4K monitor or TV has a resolution of thirty-eight forty by twenty-one sixty,

5:26 yielding around 8.3 million pixels.

5:29 Using the X and Y coordinates of the vertices

5:32 of a given triangle on the view screen,

5:35 your GPU calculates where it falls within this massive grid

5:39 and which of the pixels are covered by that particular triangle.

5:43 Next, those pixels are shaded using

5:46 the texture or color assigned to that triangle.

5:50 Thus, with rasterization,

5:51 we turn triangles into fragments which are groups of pixels that come

5:57 from the same triangle and share the same texture or color.

6:01 Then we move on to the next triangle

6:04 and shade in the pixels that are covered by it

6:07 and continue to do this for each of the 3.5

6:10 million triangles that were previously moved onto the viewscreen.

6:14 By applying the Red Blue and Green color

6:17 values of each triangle to the appropriate pixels,

6:20 a 4K image is formed in the frame buffer and sent to the display.

6:26 You’re probably wondering how we account

6:28 for triangles that overlap or block other triangles.

6:31 For example, the train is blocking the view of much of the train station.

6:37 Additionally, the train has hundreds of thousands of triangles

6:40 on its backside that are sent through the rendering pipeline,

6:43 but obviously don’t appear in the final image.

6:47 Determining which triangles are in front is called the visibility

6:51 problem and is solved by using a Z-buffer or Depth Buffer.

6:56 A Z-Buffer adds an extra value to each of the 8.3 million pixels

7:01 corresponding to the distance or depth that each pixel is from the camera.

7:05 In the previous step, when we did the vertex transformations,

7:09 we ended up with X and Y coordinates,

7:12 but then also got a Z value that corresponds

7:16 to the distance from the transformed vertex to the camera.

7:20 When a triangle is rasterized,

7:22 it covers a set of pixels and the Z value or depth

7:27 of the triangle is compared with the values stored in the Z-Buffer.

7:31 If the triangle’s depth values are lower than those in the Z-buffer,

7:36 meaning the triangle is closer to the camera,

7:38 then we paint in those pixels using the triangle’s

7:42 color and re-place the Z-buffer’s values using that triangle’s Z-values.

7:48 However, let’s say a second triangle comes along with Z

7:51 values that are higher than those in the Z-buffer,

7:54 meaning the triangle is further away.

7:56 We just throw it out and keep the pixels

8:00 from the triangle that was previously painted with lower Z-values.

8:04 Using this method, only the closest triangles to the camera

8:08 with the lowest Z-values will be displayed on the screen.

8:12 By the way, here’s the image of the Z or Depth buffer,

8:17 wherein black is close and white is far.

8:20 Note that because these triangles are in 3D space,

8:24 the vertices often have 3 different Z values,

8:27 and thus each individual pixel of the triangle

8:31 needs its Z value computed using the vertex coordinates.

8:35 This allows intersecting triangles to properly

8:38 render out their intersections pixel by pixel.

8:42 One issue with rasterization and these pixels is that if the triangle

8:46 cuts at an angle and passes through the center of the pixel,

8:50 then the entire pixel is painted with that triangle’s

8:53 color resulting in jagged and pixelated edges.

8:55 To reduce the appearance of these jagged edges,

8:59 graphics processors implement a technique called Super Sampling Anti-Aliasing.

9:06 With SSAA, 16 sampling points are distributed across a single pixel,

9:11 and when a triangle cuts through a pixel,

9:14 depending on how many of the 16 sampling points the triangle covers,

9:19 a corresponding fractional shade of that color is applied to the pixel,

9:24 resulting in faded edges in the image

9:26 and significantly less noticeable pixelization.

9:28 One thing to remember is that when you’re playing a video game,

9:33 your character’s camera view as well as the objects

9:37 in the scene are continuously moving around.

9:40 As a result, the process and calculations within vertex shading, rasterization,

9:47 and fragment shading are recalculated for every single frame once every

9:52 8.3 milliseconds for a game running at 120 frames a second.

9:57 Let’s move onto the next step which is Fragment Shading.

10:01 Now that we have a set of pixels corresponding to each triangle,

10:06 it’s not enough to simply paint by number to color the pixels.

10:10 Rather, to make the scene realistic,

10:12 we have to account for the direction and strength of the light or illumination,

10:17 the position of the camera, reflections, and shadows cast by other objects.

10:22 Fragment shading is therefore used to shade in each

10:26 pixel with accurate illumination to make the scene realistic.

10:29 As a reminder, fragments are groups

10:32 of pixels formed from a single rasterized triangle.

10:36 Let’s see the fragment shader in action.

10:39 This train engine is mostly made of black metal,

10:42 and if we apply the same color to each of its pixel fragments,

10:46 we get a horribly inaccurate train.

10:48 But once we apply proper shading,

10:51 such as making the bottom darker and the top lighter,

10:55 and by adding in specular highlights or shininess

10:57 where the light bounces off the surface, we get a realistic black metal train.

11:03 Additionally, as the sun moves in the sky,

11:06 the shading on the train reflects the passage of time throughout the day,

11:11 and, if it’s night, the materials and colors of all

11:15 the objects are darker and illuminated from the light of the fire.

11:19 Even video games such as Super Mario 64 which is almost 30 years old have some

11:25 simple shading where the colors of surfaces are

11:28 changed by the lighting and shadows in the scene.

11:32 So, let’s see how fragment shading works.

11:34 The basic idea is that if a surface is

11:37 pointing directly at a light source such as the sun,

11:40 it’s shaded brighter whereas if a surface is facing

11:44 perpendicular to, or away from the light, it’s shaded darker.

11:48 In order to calculate a triangle’s shading,

11:51 there are two key details we need to know.

11:54 First, the direction of the light and second,

11:57 the direction the triangle’s surface is facing.

12:00 Let’s continue to use the locomotive as an example

12:03 and paint it bright red instead of black.

12:07 As you already know, this train is made of 762 thou-sand flat triangles,

12:12 many of which face in different directions.

12:16 The direction that an individual triangle

12:18 is facing is called its surface normal,

12:21 which is simply the direction perpendicular to the plane of the triangle,

12:25 kind of like a flagpole sticking out of the ground.

12:29 To calculate a triangle’s shading,

12:31 we take the cosine of the angle or theta between the two directions.

12:36 The cosine theta value is 1 when the surface is facing

12:40 the light and when the surface is perpendicular to the light it’s 0.

12:45 Next, we multiply cosine theta by the intensity of the light and then

12:50 by the color of the material to get the properly shaded color of that triangle.

12:55 This process adjusts the triangles’ RGB values and as a result,

12:59 we get a range of lightness to darkness of a surface

13:04 depending on how its individual triangles are facing the light.

13:08 However, if the surface is perpendicular or facing away,

13:11 we don’t want a cosine theta value of 0

13:15 or a negative number because this would result in a pitch-black surface.

13:20 Therefore, we set the minimum to 0 and add

13:24 in an ambient light intensity times the surface color,

13:27 and adjust this ambient light so that it’s higher in daytime scenes,

13:32 and closer to 0 at night.

13:34 Finally, when there are multiple light sources in a scene,

13:38 we perform this calculation multiple times with different light directions,

13:43 and intensities and then add the individual contributions together.

13:47 Having more than a few light sources is computationally intense for your GPU,

13:53 and thus scenes limit the number of individual light sources and sometimes limit

13:58 the range of influence for the lights

14:01 so that triangles will ignore distant lights.

14:05 The vector and matrix math used

14:07 in rendering video game graphics is rather complicated,

14:11 but luckily there’s a free and easy

14:13 way to learn it and that’s with Brilliant.org.

14:16 Brilliant is a multidisciplinary online interactive education platform

14:19 and is the best way to learn math,

14:23 computer science, and many other fields of science and engineering.

14:27 Thus far we’ve been simplifying

14:30 the math behind video game graphics considerably.

14:32 For example, vectors are used to find the value of cosine

14:36 theta between the direction of the light and the surface normal,

14:39 and the GPU uses the dot product divided

14:42 by the norm of the two vectors to calculate it.

14:46 Additionally, we skipped a lot of detail when it came to 3D

14:50 shapes and transformations from one coordinate system to another using matrices.

14:55 Rather fittingly, Brilliant.org has entire

14:58 courses on vector calculus, trigonometry,

15:01 and 3D geometry, as well as courses on linear algebra and matrix math.

15:06 All of which have direct applications to this video

15:09 and are needed for you to fully understand graphics algorithms.

15:13 Alternatively, if you’re all set with math,

15:17 we recommend their course on Thinking in Code which will

15:20 help you build a solid foundation on computational problem solving.

15:24 Brilliant is offering a free 30-day trial

15:27 with full access to their thousands of lessons.

15:30 It’s incredibly easy to sign up,

15:32 try out some of their lessons for free and, if you like them,

15:36 which we’re sure you will, you can sign up for an annual subscription.

15:40 To the viewers of this channel,

15:42 Brilliant is offering 20% off an annual subscription

15:45 to the first 200 people who sign up.

15:48 Just go to brilliant.org/brancheducation.

15:52 The link is in the description below.

15:55 Let’s get back to exploring fragment shading.

15:57 One key problem with it is that the triangles

16:01 within an object each have only a single normal,

16:04 and thus each triangle will share

16:06 the same color throughout the triangle’s surface.

16:09 This is called flat shading and is rather unrealistic when viewed

16:13 on curved surfaces such as the body of this steam engine.

16:17 So, in order to produce smooth shading, instead of using surface normals,

16:22 we use one normal for each vertex calculated using

16:26 the average of the normals of the adjacent triangles.

16:30 Next, we use a method called barycentric coordinates to produce

16:34 a smooth gradient of normals across the surface of a triangle.

16:38 Visually it’s like mixing 3 different colors across a triangle,

16:42 but instead we’re using the three vertex normal directions.

16:46 For a given fragment we take the center of each pixel and use the vertex

16:52 normals and coordinates of the pre-rasterized triangle

16:55 to calculate the barycentric normal of that particular pixel.

16:59 Just like mixing the three colors across a triangle this pixel’s normal

17:04 will be a proportional mix of the three vertex normals of the triangle.

17:08 As a result, when a set of triangles is used to form a curved surface,

17:13 each pixel will be part of a gradient of normals resulting in a gradient

17:18 of angles facing the light with pixel-by-pixel

17:22 coloring and smooth shad-ing across the surface.

17:25 We want to say that this has been one

17:28 of the most enjoyable videos to make simply because

17:31 we love playing video games and seeing the algorithm

17:34 that makes these incredible graphics has been a joy.

17:38 We spent over 540 hours researching, writing,

17:42 modelling this scene from RDR2, and animating.

17:46 If you could take a few seconds to hit that like button,

17:50 subscribe, share this video with a friend,

17:53 and write a comment below it would help us more than you think, so thank you.

17:58 Thus far we’ve covered the core steps for the graphics rendering pipeline,

18:03 however, there are many more steps and advanced topics.

18:06 For example, you might be wondering where ray tracing

18:09 and DLSS or deep learning super sampling fits into this pipeline.

18:15 Ray tracing is predominately used to create highly

18:19 detailed scenes with accurate lighting and reflections typically found

18:23 in TV and movies and a single frame

18:26 can take dozens of minutes or more to render.

18:29 For video games, the primary visibility and shading of the objects

18:34 are calculated using the graphics rendering pipeline we discussed,

18:37 but in certain video games ray tracing is used to calculate shadows,

18:43 reflections, and improved lighting.

18:44 On the other hand, DLSS is an algorithm for taking a low resolution

18:50 frame and upscaling it to a 4K frame using a convolution neural network.

18:57 Therefore DLSS is executed after ray tracing

19:00 and the graphics pipeline generates a low-resolution frame.

19:04 One interesting note is that the latest generation of GPUs

19:09 has 3 entirely separate architectures of computational resources or cores.

19:14 CUDA or Shading cores execute the graphics rendering pipeline.

19:19 Ray tracing cores are self-explanatory.

19:21 And then DLSS is run on the Tensor cores.

19:26 Therefore, when you’re playing a high-end video game with Ray Tracing and DLSS,

19:31 your GPU utilizes all of its computational resources at the same time,

19:36 allowing you to play 4K games and render

19:40 frames in less than 10 milliseconds each.

19:42 Whereas if you were to solely rely on the CUDA or shading cores,

19:47 then a single frame would take around 50 milliseconds.

19:51 With that in mind, Ray Tracing and DLSS are

19:55 entirely different topics with their own equally complicated algorithms,

20:00 and therefore we’re planning separate videos that will

20:03 explore each of these topics in detail.

20:05 Furthermore, when it comes to video game graphics,

20:08 there are advanced topics such as Shadows,

20:11 Reflections, UVs, Normal Maps and more.

20:14 Therefore, we’re considering making an additional

20:17 video on these advanced topics.

20:19 If you’re interested in such a video let us know in the comments.

20:23 We believe the future will require

20:26 a strong emphasis on engineering education and we’re

20:29 thankful to all our Patreon and YouTube

20:31 Membership Sponsors for supporting this dream.

20:33 If you want to support us on YouTube Memberships,

20:37 or Patreon, you can find the links in the description.

20:41 This is Branch Education, and we create 3D animations that dive deeply

20:46 into the technology that drives our modern world.

20:49 Watch another Branch video by clicking one

20:52 of these cards or click here to subscribe.

20:55 Thanks for watching to the end!

Study with Looplines Download Captions Watch on YouTube