Rendering 3d From Scratch Chapter 8 - Conclusion

3d scene, bruh
camera x
camera y
camera z
camera size

The demo above is the culmination of all of what we’ve learned in this series. This is all just plain javascript operating on the page, so feel free to inspect the code to see what’s going on. Bonus points if you find the code that’s drawing the new icosphere.

I hope you had fun on our journey from blank page to glorious 3d scene, but I have to admit that we’ve really only scratched the surface. My hope for this series is that it gave a decent primer to some of the core ideas behind 3d programming, such as:

  • Representing points in space

  • Direction vectors

  • Dot products and cross products and their uses

  • Filling in polygons on a screen

  • Screen and depth buffers

I think the best way to conclude a journey is to plan the next one, so let’s talk about what where can go next with 3d rendering:

Matrices

I intentionally avoided matrices in this series because I think they can be a major turnoff if you’re not mathematically inclined (I’m not) and you just want to put some stuff on the screen. But if you Google around for 3d programming tutorials, matrices is one of the first things articles will discuss, and there’s good reason for this. Matrices are an incredibly powerful tool that allow you to represent entire coordinate spaces as a single matrix and translate from one coordinate space to another with a single operation. They are difficult to learn at first, and it takes time for them to “click”, but once they do, they’re an invaluable tool in the toolchest and you can’t do anything serious in 3d without them. Matrices would actually simplify a lot of this code, such as converting our object coordinates into screen space.

wiki image for matrix math

wiki image for matrix math

Texture Mapping

We drew our objects with single colors, but objects in real life are rich with many colors and textures. One common way 3d applications achieve more detail in objects is with texture mapping, where a 2d image is “mapped” onto a 3d shape. One of the simplest forms of texture mapping is to add colors to faces, but texture mapping extends far beyond this. You can also add subtle surface detail like nooks and crannies that the lights in your scenes can interact with! This technique is often called bump mapping, normal mapping, or height mapping. Then, you can take this a step further and add different “shininess” values via a texture (imagine a tree with shiny leaves and non-shiny bark). This technique is called specularity mapping.

2d textures can be applied to 3d polyhedra

2d textures can be applied to 3d polyhedra

Lighting

Our objects are all flat lit. I think it looks pretty neat and stylistic, but what if we wanted to add some dynamism to our scene? One way we might do this is to add lighting. Lighting uses algorithms to simulate how light interacts with objects in real life. When calculating an object’s color, you incorporate the effect of lighting based on the properties of the object (is the object metallic, for instance). With different types of lights, you can change the entire mood of a scene. Lighting is a huge step towards realism, but once you incorporate lighting, you run the risk of entering into the uncanny valley unless you also implement shadows!

simple scene with basic lighting and no shadows

simple scene with basic lighting and no shadows

Shadows

Shadows and lighting walk hand in hand. Scenes look weird if you only have lighting, or only have shadows. However, shadows are their own can of worms! Once lights are added, a technique known as “shadow mapping” can be used to simulate the effect of shadows. Shadow mapping entails that you render a scene from the point of view of all of your lights in order to obtain “shadow depth maps”. Then, once you render the full scene, you can use your shadow maps to determine which parts of your scene are in shadow. It’s actually quite similar to how we implemented depth mapping, but it requires that you can freely translate a point in space from screen space to light space, which is most easily accomplished with matrices.

shadows enhance the realism of light even further

shadows enhance the realism of light even further

Some Final Words

There are countless fascinating topics in 3d rendering, and I encourage you to dig deeper. Yes, there is a difficult learning curve, and you have to internalize some concepts from linear algebra, but being able to write software to create three dimensional scenes is one of the more rewarding experiences in programming. Now go forth, and create amazing stuff!

Jon BedardComment