I thought of an approach to ray-tracing that could result in faster performance using symbolic evaluation. I mention it here to illustrate the benefits of thinking symbolically and also because I don't see myself writing a ray tracer anytime in the next decade.
Images typically contain stretched out areas that correspond to the surfaces of individual objects. While each pixel in an area may have a unique color value, all of the pixels may easily computed by a single, simple function, even for textured surfaces. In theory, the applicable area of a function could be extended to the full dimensions of the image by using conditionals, but such a function would be unwieldy.
Instead of calculating a color value for each ray we shoot out from each screen pixel, we could produce a partially evaluated function that returns a color. (This could work recursively in the event of reflected surfaces.) The computation for a single pixel would suffer, but the function could be reused to fill out the area occupied by adjacent related pixels, which also share the same function. Search and anti-aliasing costs for these pixels would be eliminated.
One approach to area detection is to produce a second function, which returns a boolean value indicating whether the first function is still valid for a given point, based on the information gathered from intersection tests of the original pixel. The second function basically serves as the boundary test for the flood fill operation. With this approach, we have the choice of making our first function a compiled function constructed from closures, a partially evaluated function represented as data, or a combination of both. Compiled functions might be faster, but data representations, being symbolic, could produce exact results.
Since this approach reduces work for typical images, I suspect that high quality images could one day be produced in the same amount of time that lowest quality images currently take without special hardware.
I don't think your idea will work.
The bottle neck in ray tracing is intersection testing. It seems your method would require the same number of intersection tests to determine if the previous partially evaluated function was still valid, and then some extra to recompute it if it wasn't valid.
Posted by: Ringo48 | August 17, 2007 at 06:25 PM
The difference is that the information from the intersection tests from the first function would be used to establish a window around the pixel which the function would remain valid.
If our ray just misses another object, we record the margin of the miss.
There might be more work involved or more complicated calculations during the intersection tests to come up with or narrow the window "of opportunity."
These values are stored inside the closures, or incorporated into the data representation of the function, which can partially evaluated.
The second function just detects whether the pixel falls inside some precomputed window, possibly after some mapping calculations.
Posted by: Wesner Moise | August 17, 2007 at 08:25 PM