Skip to content

A C++ program that will create 3D renders using the well-known raytracing algorithm technique.

Notifications You must be signed in to change notification settings

ethangutknecht/RaytracingProgram

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 

Repository files navigation

🎯 Raytracing Program


Directory
🎓 About The Class

ℹ About The Program

🧮 The Fancy Calculation Features 🏁 The Final Beautiful Renders




⚠ ⚠ ⚠ DISCLAIMER ⚠ ⚠ ⚠
I AM UNABLE TO POST THE SOURCE CODE FOR THIS SPECIFIC PROJECT DUE TO THE PROFESSOR'S COPYRIGHT ON THE SKELETON THAT THE PROFESSOR ORIGINALLY GAVE



🎓 About The Class

CSE386 - The Foundation Of Computer Graphics

I took this class in my junior year of college, and it brought a heavy focus on vectors and vector arithmetic. Mastering the skills of normalizing, morphing, and creating vectors was a dependency to do all of the fun stuff later down the road. We first learned about raytracing; this process takes every pixel and computes a color based on the “shapes” within the scene. Compared to an “object-ordered” algorithm, it is much slower in computation time, but it gave me a great understanding of how 3D scenes are rendered on computers. Late in the class, we learned about “object-ordered rendering,” an algorithm that computes the color of shapes by object rather than by pixel. The course was a marathon rather than a sprint, as the syllabus built each topic on the other. Overall, it was an impeccable class, and I would recommend anyone to learn this stuff if they have the opportunity.




ℹ About The Program

This program revolves around the concept of raytracing. Raytracing is a term for a fancy algorithm that renders 3D images in computer graphics. The algorithm takes a viewing ray for every pixel within the window, “shoots” them into the scene, and calculates a color for the corresponding pixel. For example, if a window is 200px by 100px, there will be 20,000 pixels, thus 20,000 viewing rays. After the algorithm calculates the viewing rays, the algorithm will show the frame. The calculation process for a single pixel can be as complex as you want it to be! For example, if I wanted my image to be super detailed, I could add shadows, reflections, anti-aliasing, transparent objects, etc. On the flip side, you can also make it very simple, only showing the ambient/silhouette of the things within the scene. The possibilities are truly endless. The process describes the flawless elegancy of programming.




🧮 The Fancy Calculation Features

⭕ Anti-aliasing

This is an elegant feature you probably experience every day but are unaware it’s happening! This feature takes a nice ridged edge and will make it round with one simple calculation. You can choose to do many different intensities, but for the sake of our program, we decided to use a three-by-three grid. This will take a pixel and get the sum of every pixel’s colors (RGB) by shooting extra viewing rays to the surrounding pixels. Afterward, it will take the current pixel and reassign it with the average color, creating those buttery smooth images.

Example of a 3x3 grid:

Before After
Before_Visual After_Visual



💡 Cones & Spotlights

These two features go hand in hand. A cone is a minor feature that uses the quadratic surface equation of a parabolic cylinder to create the shape’s properties. A little extra work is needed to let the program know not to keep producing the shape above the tip of the cone. A spotlight is a cone, but it is light instead of a physical form. Anything within the "light cone" will be illuminated, but anything outside will show the object ambient. The base's index position, height, and radius will be specified when creating the cone.



🔃 Reflections

This is my favorite feature of this program. This feature ultimately allowed us to create mirrors within our scene. Here is the recursive process of how it works:

  • Ray shoots and hits an object
  • Reflection vector is shot away from the original hit object
  • If the reflection vector hits another object, repeat. Otherwise, end
  • Add each color * 0.3 to the final color
Allowing 0 Recursions Allowing 1 Recursion Allowing 2 Recursions
Image_1 Image 2 Image_3

My program allows it to specify how many recursions to do. I always set it to three since doing more seems to diminish returns. Finally, I also had to consider surface acne when coding this. So every hit is slightly moved above the surface by a tiny factor of 0.01 units.

Example Of Surface Acne:
Example_Of_Surface_Acne

Example Of Reflections:
Example_Of_Reflections



🌇 Shadows

The shadows make the lights and objects in the scene feel real. When a ray hits an object, it will shoot rays at every light object. If those rays intersect with another opaque object and the light intensity is large enough, it will produce a shadow for the other opaque object. This also calculates multiple lights in the scene so that the shadow is accurate. These rays that shoot out to the light object are called shadow feelers. Surface acne will also be considered, thus moving the hit 0.01 units above each surface.

Before After
Before_Visual After_Visual



📷 Viewports

This feature allows you to look at multiple different camera angles simultaneously. This will split the window into different sections, rending the same scene from multiple camera angles. How does it work? It calls the render frame function many times and specifies how big the size of the render should be. It will also determine where those pixels should be based on the start position.

Rendering Sections Camera Positions
Sections Cam_Positions


Example Of Viewports:
Example_Of_Viewports



🎨 Textures

Textures are pretty simple. Put an image on an object. It becomes pretty easy for objects like a plane or a single side of a cube. The challenge comes when you map the object onto a 3D surface. I used mapping an American flag onto a cylinder's side as an example. This wraps the flag around the cylinder, similar to how you would with a can of soup. Next, there had to be some computations involving mapping the size of the image in pixels to [0, 1]. Once that mapping computation is complete, it’s pretty simple to find what color that pixel needs based on the image map, lighting, etc.



🌫 Transparency

Transparency is one feature that takes the program from good to great. This program has a set of opaque objects and a set of transparent objects. When a viewing ray hits a transparent object, it will continue to shoot past, looking for more objects. There are different cases:

  • Hits another opaque object
  • Hits the "sky" or no object
  • Hits another transparent object

Based on these cases, we would combine the colors with whatever it hit and the transparent object's color. Overall, the entities behind a transparent object would look like a tint varying by how transparent the object is. In the example below, the red plane intersects the scene making everything "behind" the red plane have a red tint.


Example Of Transparency:
Example_Of_Viewports







...🥁now lets put it all together...drumroll please🥁...







🏁 The Final Beautiful Renders

Image_1 Image_2 Image_3 Image_4







Copyright © Ethan Gutknecht 2022

About

A C++ program that will create 3D renders using the well-known raytracing algorithm technique.

Topics

Resources

Stars

Watchers

Forks

Languages