As one of the learning objectives this trimester, we were tasked with optimising a raytracer given to us, to the best of our ability. All the leading numbers for each picture description, are shown in milliseconds taken to complete the raytrace 100%. As an example, the first time shown, the base time, would be just over 59 seconds.

59096 – This is the base time with no changes to the raytracer program.

31136 – This is the time for the base raytracer program, except I turned shadows off. I decided that I wanted to make beating this number my goal, without using OpenMP.

53647 – Reflect twice not thrice. This is the first thing I tried, by default the raytracer allows for 3 reflection bounces, I set it to two and it made a 6-ish second difference with only minimal changes to reflections of reflections of objects.

39337 – Skipped checking for light 0. There are two lights in the scene, a red one and a white one, I disabled the check for the white one and it made a massive difference! You can kind of se on the right side of the bed of spheres that there is more red light, but I believe it looks better anyway, hence why I kept it.

37880 – Slightly changed LUA file. The “power” value for the bottom bed of spheres was 5, I set it to 1, you can see a shadowing difference for sure, but I asked Carlos what image he thought was the base image between this one and the base one, and he thought for sure this was the base image and I agree with him that it looks better 😉 It is only a matter of 2 seconds though, but I am keeping it.

33839 – More slight changes to the LUA file, disabled the reflective attribute of the bed of spheres, it didn’t seem to make any difference in looks, but it made a 4-ish second difference in completion time!

30587 – I added a more efficient sqrt algorithm, it only saved me around 3 seconds total, but I had finally passed the time I wanted to beat, the time of the base version of the raytracer except disabling shadows.

22281 – I was now happy that I had passed the time I set myself to pass, now I could activate OpenMP and really see how good I could make it.

16321 – I had previously set main_disp.set_normatization to 1 to test if normalisation would better the time, it totally didn’t, setting it back to 0 shedded around 6 seconds off of the time.

9926 – Edited the LUA file another tad, this time only spawning balls that will be visible on screen, saved a hell of a lot of time, another 6.5-ish seconds. I must admit the average time is between 10.5 and 11 seconds for this one. (You can see the reflection of the bed of balls in the spiral of spheres, but it shows no change to how many balls are visible on the actual bed of balls.)

Between 9835 and 9390 – Final changes – I didn’t like how obvious the change to the “power” attribute was in the LUA file, so I changed it back from 1 to 4. I ran the raytracer from a cold computer, 6 times, once every minute, and through all 6 times, the number never went over 9835ms! I am soooo glad I can get consistently under 10 seconds!

Things I tried but failed:

Running the sky image through a program that cuts down the size of BMPs. CImg now couldn’t read the BMP.

Making the image a PNG, including the libpng library for CImg to be able to read it. The libpng library couldn’t find the reference to one of it’s files even though I pointed it directly to tat file’s location.

Removing the specular and diffuse calculations, it made too much of a difference in looks but no difference in speed.

Setting main_disp.set_normatization to 1. Thought maybe normalisation may speed things up, I don’t know why, its just an extra step, changing it back to 0 shaved 6 seconds off again.

Putting the improved sqrt method into the kf library for it to use on vector math, it was coming up with a const-related error and I couldn’t be bothered trying to solve it for the few milliseconds I predicted it would shave off.

Tried an Assembly solution for the sqrt algorithm, C++ understood all the syntax given, no errors there, but it would still complain and wouldn’t build.

Right after changing the reflection amount from 3 to 2, I wanted to see what setting it to only reflect once would look like, it took 20 seconds shorter (which amazed me), but it looked too much different from the original to keep.

Tried setting main_disp.set_normalisation to 2, and I got some really cool looking results as you can see below, but it added 4 seconds to the time (did this after the 16321 version and got 20016 setting normalisation to 2).

In the end I think it was a pretty big success, cutting down the time it takes the raytracer to complete by 50 seconds! Sure the 9 second time was only once, but it still happened, I swear, I have proof! 😀 Anyway, here is a final comparison between the base raytracer image and the completed raytracer image: