Image by author

Exploring Computer Graphics: Weekly Chronicle #7

Eric Buitrón López
Technological Singularity
7 min readJan 22, 2024

--

Originally published at https://eric-buitron.hashnode.dev on January 21, 2024.

Overview

Hello everyone, it’s been a couple of demanding weeks at work, but I’m back with another weekly chronicle. I was able to make some progress in each project and the main highlight is that I validated the ray tracing in Rust project. Let’s go right into the content of the week!

My Journey into Computer Graphics

Learning Rust

As I mentioned last week, my goal before continuing with the newly restructured project, was to complete the Rust 3D Graphics in the Browser series from Doug Milford’s YouTube videos. First of all, the series went into 2D graphics in the browser using WebGL. This is the result of that part:

Image by author

Then, the series went into 3D graphics, where the first task was to define the plane with perspective view:

Image by author

Then, I added mouse inputs to be able to rotate the plane.

Image by author

After having mouse controls, the series went over adding a sin wave to add color to the plane depending on the y-axis value (green for positive and red for negative).

Image by author

With this out of the way, the series went into animating the sin wave and adding Phong lighting. This was the final result:

Image by author

For some parts it felt like I was just blindly coding alongside the video series. However, completing it allowed me to get a better understanding (and a complete project codebase) of Rust. Besides, it allowed me to enhance my understanding of the setup that must be done to use OpenGL (or WebGL in this case) and draw 3D graphics.

Ray Tracing from the Ground Up in Rust

With the tutorials out of the way, it was time to see if I’d be able to follow alongside the Ray Tracing from the Ground Up book (which is based in C++) while using Rust. The first part involves creating a bare bones ray tracer. In the book, the author points towards a skeleton codebase which already has the implementation of the bare bones ray tracer. However, the webpage that is mentioned is no longer maintained. I managed to find this repository of someone who implemented the exercises of the book and the exact commit where they set up everything to work for the skeleton ray tracer. The repository is also in C++, but it allowed me to have another reference besides the book of the basic code that I should be able to set up in Rust for this project to work.

First of all, I made sure I could get SDL2 (A cross-platform development library that I’ll use for handling input and window management) running. To do this, I simply created a window that changed colors in the main function of the program.

Image by author

The next part was to implement a Window class instead of just creating it in the main function. To test it, I drew a single red pixel to the black background screen not too far below the word “from”. It might be difficult to see in the image, but the pixel is actually there. This gave me hopes that I would at least be able to replicate the skeleton code for the ray tracer.

Image by author

However, Rust doesn’t really have classes. It has something called a struct which behaves similar to a class in other languages but not exactly the same. For example, as I mentioned last week, there isn’t any inheritance and there isn’t any polymorphism. At least in the same way that you’d expect from other object-oriented programming (OOP) languages. In fact, the official Rust programming language book, mentions that Rust can both be and not be an OOP language. Everything depends on how you define one. This would prove to be a more difficult challenge than I expected since I couldn’t simply replicate the classes from the repository with the syntax of Rust and call it a day. I actually tried to do so and got a bunch of compiler errors.

To be able to compile my program I had to change some parts of the design and implement them in a way that would work in Rust. If you’re interested in checking out how the code ended up and want to follow along, you can check the GitHub repository for this project here. The first test scene of the ray tracer consists of a single red sphere with a black background. This is what I got when I finally managed to compile and run the program:

Image by author
Image by author

I was getting some weird shadow-casting oval (which disappeared as soon as I moved the window) at the center of a white canvas. Besides, a second window with the black background was being created. After inspecting my code for a while, I was able to find the solution, and everything basically boiled down to problems with how I was using references and handling the ownership of the objects in my program. After fixing this, I was able to render the first scene:

Image by author

However, the program was still creating 2 windows, one with the correct size and another one where the ray tracing worked. After I fixed this, I was able to properly render the 3 scenes of the bare bones ray tracer chapter. Note that for the last scene I only include the image since the ray tracing took longer than I was willing to wait for generating a gif.

Image by author
Image by author
Image by author

My Journey into OpenGL

For this project I completed the basic lighting and materials section from Learn OpenGL.

Basic lighting

In the basic lighting section, I started implementing ambient lighting. This type of lighting simulates the constant light that is always somewhere in the world (either from the sun, moon, or other distant light).

Image by author

Then, I added diffuse lighting. This type of lighting simulates the directional impact that a light has on an object.

Image by author

And I finally added specular lighting. This type of lighting simulates the bright spot of a light that appears on shiny objects.

Image by author

This allowed me to have the Phong lighting model implemented in my scene.

Image by author

Materials

The materials section consisted of expanding the previous section by adding a material structure to the fragment shader. This allows creating different materials that could be used to replicate different objects from life such as gold, emeralds, or plastic.

Image by author

My Journey into Shaders

This week I learned about textures and normal mapping with Ben Cloward’s Shader Graph Basics YouTube playlist. There isn’t really anything to show since I just took some notes while watching the videos. It helped me understand the best ways to import texture maps into game engines and some tips on how to blend normal maps together to produce higher quality materials.

See you next week!

Here are my goals for next week for each project:

See you next week!

--

--

Eric Buitrón López
Technological Singularity

I'm a Full Stack Developer & Game Developer. I love learning new stuff related to game development. I look forward to sharing some of that progress with you!