Shedding Some Light on Ray Tracing

Hi everyone! , I’m Samyak, 1st Year undergrad at IIT Roorkee, studying Applied Mathematics, and this past week I tried understanding what Ray tracing is, and this blog would be a brief description of that journey.

For starters, rather than straight-up jumping into what ray tracing is and how it works, let’s try to understand how traditional computer graphics and rendering techniques work.

Rasterization

Rasterization is probably the most commonly used rendering algorithm.

Images in computer graphics are presented on some kind of “raster display”. Raster displays show images as rectangular arrays of pixels, the monitor you are using is an example of a raster display, which is made up of an array of “pixels” (short for picture element), these pixels can be set to different colours(RGB) to achieve any desired output image.

In rasterization the GPU, is fed with instructions to “render”(draw) 3D scenes onto 2D planes using simple polygons(triangles are the most widely used ones, though a few other polygons are also often used), these polygons are then “rasterized”(transformed) onto individual pixels, and then further processes such as colouring, shading, textures are added on top of it.

One nice trick that rasterization uses to render 3D objects and scenes is that it associates every vertex/polygon with a depth factor, meaning when viewing objects from different angles, only that part is visible which is at the top.

Vertices (and by extension polygons formed due to these vertices) located nearer to the “camera” are drawn above objects located far from the camera. The depth factor is inversely proportional to the distance of the object from the camera.

The process of calculating the vertices that make up the object, then joining them to make polygons, and then applying textures and shading is part of a special software-hardware subsystem called the Graphics Pipeline, and these are usually implemented using graphics API (a few of them are OpenGL, Vulkan etc..).

Phew!.. now that rasterization is out of the way, why don’t we have a look where traditional rasterization lacks…

As you might have been able to point out, the most notable difference is that, since rasterization is geometry-based rendering, simulating real-life or photorealistic imagery through rasterization is quite difficult.

For example simulating reflections, refractions, realistic shadows and textures are difficult through rasterization, because this method has a hard time tracking exactly how light should bounce in and around an image space.

Notice the difference in reflections and textures on the spoon, cup and kettle.

Ray Tracing

Before understanding what ray tracing is (this is the second time I’ve said this….. I know, bear with me :) ), let’s just do a simple activity :

Look around where you are sitting, there must be a light source, probably a LED or even the Sun, now imagine rays emitting from your eyes(and, no this isn’t a Terminator reference), follow (or “trace”) the path taken by those rays towards any object (maybe even the wall), and follow the path the ray takes after bouncing off the object towards the light source.

That’s ray tracing.

Now make a computer do it, for ALL the objects in the room(or just the few you are interested in), also account for shadows, textures, the reflectivity of surfaces, ambient light in the room, do it 60 times per second(or generate 60 ray-traced frames(images) per second) and you have a ray tracer.

Now… in actual things are way more complex than this, but this is probably one of the simpler explanations.

One thing I would like to say is doing stuff in computer graphics has a slim margin for errors, if you miscalculate even a little, the output would be a black screen with no output, not to mention other abnormalities and absurdly large or tiny images.

Moving onto a bit technical side of things, here’s an image that sums up the above paragraph.

You send rays through the “eye” ( camera) through each pixel and try to trace a path to every object in the scene to be rendered.

Rays from eye E, through a pixel matrix

To point out the difference between rasterized graphics and ray-traced graphics think of the nested loops used for rendering any scene :

In the case of Rasterization the loop looks something like this:

Rasterization loop

while for Ray tracing :

Raytracing loop

One nice, fact? ..thing?.. observation? .. about ray tracing is that the solution to most problems ( which also is quite obvious ), is just

trace more rays”

Want shadows? trace rays from point of intersection with the surface, to the light source and check if the new ray intersects any object before it reaches the light source, if it does, then that pixel is under the shadow of some other object.

Want reflections? trace reflected rays from point of incidence.

Refraction? trace more rays using Snell’s law but inward and as you might guess.. trace those rays once again at the exit point and check for further reflections, and refractions.

To sum up the above discussion: For any ray tracer the basic tasks are :

  1. Ray generation: for each pixel calculate the origin and emit a ray through that pixel according to the camera/viewing position.
  2. Ray — object intersection: figure out the closest object that the ray intersects (for any particular pixel)
  3. Shading/colouring: figure out a colour for that pixel based on desired textures and ray-object intersection.

What I’ve been working on?

Now moving onto the project that I’ve been working on :

A simple C++ based raytracer. Here’s the link for the GitHub repository.

If you want to run it on your system it is quite simple, just run the make commands in your terminal and you would have an out.ppm file in your directory, open it using GIMP or Photoshop.

Here are a few outputs :

A simple linear blend based on an affine combination of two colours, the gradient or simply the colour of any pixel is determined by the position of the pixel on the Y-axis, darker pixels are the bottom.
And NO, those are not shadows, that’s just some clever background blend
This and other images can be obtained by changing the scaling factor of Normals

The current image displays an image consisting of a sphere, and a linear blend background with just the bare minimum shading based on the normal vector at the point of intersection of the ray emitted from the camera and the sphere’s surface.

Trying to fit in two spheres.

The spheres in the image on the left have a larger radius, than the ones on right and are closer to the camera / “screen”, also the spheres on the right (yes those are spheres, at least mathematically!) seem a bit distorted due to perspective projection.

Conclusion:

It was quite an awesome learning experience, understanding how stuff works around graphics.

Moving forward I would be trying to improve the project I’ve been working on, maybe add reflections, better shading and other stuff.

Resources and useful links :

  1. Fundamentals of Computer Graphics by, Steve Marschner and Peter Shirley.[Book]
  2. UC Davis, Introduction To Computer Graphics,2009, (the lecture on Ray Tracing in this playlist is quite good)
  3. “Ray Tracing in One Weekend Series” by, Peter Shirley
  4. tinyraytracer
  5. Scratch A Pixel

Thanks to the original author Samyak Wanjarwadkar for writing this awesome article!.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
ACM Roorkee

We are a bunch of enthusiastic students who aim at uniting the computing fraternity at IIT Roorkee under one tag.