I took an object-oriented design approach, keeping different components as separate as possible from one another. I ended up with the following design:
- Camera - represents the camera. Stores it's position, up, and forward vectors. Doesn't bother storing the right vector as that can be quickly determined with a cross product. Also contains the "render" method; it takes in a World object and does the ray-casting, returning a 2D array of Colour objects (the final image to be displayed).
- World - stores a list of 3D objects to be rendered. That's pretty much it. Also contains a method to transform all those objects based on a transformation matrix, but it isn't used yet.
- Object3D - represents an object to be rendered. It's an abstract class and contains one method that must be implemented by all child classes; intersect(Ray).
- Vector3 - represents a 3D vector, and implements all the standard vector math functions.
- Point3 - represents a 3D point. Essentially a vector, but without the vector math functions.
- Ray - a point (Point3) with direction (Vector3).
- Colour - stores a red, green, and blue value.
Known Problems
I have a variable that sets how far away the "screen" that the rays shoot through is. Unfortunately, if I try to position the screen correctly (in between the camera position and the scene), everything that rendered is too small to see. Instead, I position it on the opposite side of the scene. I get desirable results, but it's such a hack that it makes me upset. It'll hopefully be fixed by next release.Additionally, the actual drawing to the screen is currently done with OpenGL ( glRect ). I feel like using OpenGL for just that is a bit overkill, so I'll be looking into alternatives.
Results
Ray Casting, no extras |
Ray Casting with Super Sampling |
I rendered the super sampled image with a rather large offset value to show the results. In practice the value would probably be much smaller.
No comments:
Post a Comment