Home About the Game Controls Downloads

What is 3D Pong?
3D Pong is where you have a hallway that the ball can bounce down and you have a paddle at each end of the hallway which will attempt to return the ball back down the hallway to the opponents end.

Making It Ray Traced:
We took a normal ray tracer and modified it to be used for specific shapes that were used in the game. These shapes are spheres and planes. It will take the scene at a current moment in time and launch rays out from the camera and return the color of the object at the hit point that it computed.

Optimizations:
Since the game is suppose to be in real-time but a ray tracer is generally not real-time, we had to make optimizations to our ray tracer. These optimizations attempted to make the ray tracer run a close to real-time as possible.

The first optimization is that any values that could be pre-computed were so that the ray tracer did not have to slow down and do those computations itself.

Second is that we realized only objects that were moving in the scene needed to be ray traced again for each frame. The walls are not reflective or refractive (preventing confusion as the ball travels down the hallway) so they do not need to be recomputed. In order to make sure that we never had to re-compute the walls we ray traced only the walls at the beginning of our program and stored the results in an array. This allowed us to use the wall values whenever we wanted within the program.

Third is that since we knew that we needed to ray trace the paddles and the ball every frame, we made sure that we kept the area we were computing as small as possible. We were able to do this with the paddles quite easily since we had their center position and also with the fact that they would never change size. So we modified the ray tracer so that it would only check a certain distance around the center position of the paddles thus keeping computation to a minimum. The sphere on the other hand posed a more difficult problem since its size changed as its z-position changed. In this case we decided to make our area that we checked for the ball the same size all the time and to make it so that it would work with the ball at its maximum size.

To demonstrate how much of a change these optimizations made, here are the amount of pixels checked each frame before and after the optimizations were implemented.


Before:   400 x 400  = 160,000 pixels
After:   (70 x 80) + (60 x 60) + (16 x 16)   =     9,456 pixels
The 70 x 80 is the front paddle box.
The 60 x 60 is the balls box.
The 16 x 16 is the back paddle box.


So already from these 3 optimizations we can see that there is a drastic change in the number of pixels that we are computing at every frame. This of course is excluding the initial computation of the walls at the beginning of the program but that is just 160,000 pixels once which simply delays the start of the program but never affects it again. The reason we can use those check boxes is because we have computed the background and so if we do not check the pixel in those boxes then we just give that pixel the color that was computed for that pixel at the beginning of the program.

The fourth optimization that we made is the removal of slow data structures from the program. Since the number of objects we have in our game is constant and also small we decided to get rid of the linked lists and use arrays. This means that we can have order 1 access to all the objects and their data.

The fifth optimization that we decided to implement was the use of the geometric ray to sphere intersection method as opposed to the algebraic way of doing it. Using the geometric way allows the ray tracer to quickly determine if it doesn’t intersect with any objects quicker.

The sixth and most important optimization that we made was using threads. We used threads when drawing the two paddles and the ball. First the back paddle would be drawn with one half being done using a thread. The once the back paddle was done then the program would draw the ball. Again one half of the ball was done using a thread. Then after the ball was drawn the front paddle was drawn in the same was as the back paddle. The use of these threads becomes apparent when using a computer with a dual core processor. This is because it is able to do the calculations for each half of the object at the same time it is doing the other half.

The combination of these optimizations ended up making the game run at an acceptable speed.