Raytracing + Pixel Shifting

Home --> Programming Projects --> Raytracing --> Raytracing + Pixel Shifting

Basic Idea

Consider rendering a first person computer game. Every cycle the entire screen is being redrawn (it would be strange not to do this!). When the player turns his head, for instance, the entire screen is likely to change. Imagine that the cost of determining the color of each pixel on the screen each frame is high. If we could somehow "move" the pixels on the screen everytime the player turns his head or walks, we would partially construct the next frame to be rendered. Of course, there will be holes and all sorts of bizzare artifacts. The goal is, however, to partially remove these artifacts by selectively rerendering part of the screen (rendering only a small portion of the pixels on the screen can be accomplished by raytracing). I call this algorithm (that moves pixels on the screen from one frame to next frame leaving holes that need to be filled) Pixel Shifting.

Thus, we want to be able to freely alow the user to move through a world while only computing the color of a fraction of all the pixels on the screen per frame. The paridigm is to keep track of what information is already on the screen and what information is being added (sort of like in video compressing). Many scenes are too dynamic for this method to work. However, static scenes (scenes where nothing is moving except the camera) with diffuse surfaces (surfaces whose lighting looks the same when being viewed from any angle) may be animated with this method.

Why Raytracing?

The point of this method is that only part of the pixels on the screen need to be redetermined from the world. With raytracing, we can cast a ray into the world for each pixel that we are unsure about. The amount of computations being done would be proportional to the number of rays being cast into the world. Rasterizing, on the other hand, would not be doing work proportional to the small number of pixels needing to be refreshed (because rasterizing is designed to refresh the entire screen so it would be doing extra work). Again, the premise is that only a relatively small number of pixels on the screen need to be refreshed each frame.

Implementation

I wrote a computer program to perform this algorithm for a Computer Vision class final project. Note: the teacher was a little mad because it is really not computer vision. The algorithm loosely falls into the category of image based rendering (but with way more information (depth information) than what most image based rendering algorithms are allowed to use!) It might be that this algorithm already exists but with a different name, but I was unable to find it in the literature (maybe Computer Vision isn't the right place to look!)

Here is the final project paper that describes the algorithm that I worked out. The algorithm is not very complicated. It is not exactly "pixels" that are stored but "points in 3d space". Points have various information associated with them such as 1) position in 3d space, 2) color and 3) when was the point added. These points are then used to determine the color of each pixel in the frame to be rendered by using bilinear filtering. These points are stored in buckets (one bucket per pixel), and points are thrown away when there are too many points per bucket (always throwing away the oldets points so errors do not accumulate). Of course, points could be stored in some other fashion (such as in buckets that correspond to different longitudes and latitudes of a sphere surrounding the camera). It is tempting to "merge" points together combining all their attributes, but this leads to horrible artifacts! Parts of the screen that have the least of information (which is determined by counting the number of points per bucket) are candidates for where rays are shot into the world for raytracing.

The above left picture shows a frame being rendered normally, and the right picture shows the frame that is rendered only by shifting pixels from the first frame according to how the camera was moved.

This algorithm (and its implementation) is far from complete. For starters, the algorithm needs to be better at temporarily filling in holes in the image to be rendered. Secondly, the algorithm really needs to implemented on a GPU! The latter seems plausible, as the alrogithm is really quite simple.

Interesting Benefit

One very useful aspect of this algorithm is that rays can be cast into the world on a remote machine and this pixel information can be sent to the user's machine. Even if the information arrives late, the updated pixel can just be "moved" according to how the user's camera moved from when the pixel should have arrived to the present. This is a neat feature of the algorithm.

Potential Use Case

Consider a first person online game where users can view vast amounts of information in the distance. We can assume that all the moving objects in the distance will be too small to view. The scene in some reasonable radius of the user can be rasterized normally, whereas everything beyond this radius is treated as a background that is rendering using the Pixel Shifting algorithm. As the user moves from area to area, the background gradually changes (remember that the algorithm throws out the oldest points). With this method, "low level of detail" versions of far away objects are not needed.

Moving Objects in the Scene?

One can imagine extending this algorithm to work in more general situations, but that is really pushing it to the limit! For example, if the scene has moving objects, then pixels being stored on the screen can be "associated" with those objects; those pixels are moved not only according to how the user moves, but also according to how the object moves. A much greater problem, however, is caused by the shadows that are created by moving objects. A moment's thought is enough to see that this is an unmanageable situation!