This is my attempt at creating a ray tracer in Haskell for the function programming competition for INF1-A Introduction to Computation at University of Edinburgh. Since, I don't have any experience with ray tracing or even intermediate level computer graphics, this ray tracer was written following along with the excellent Ray Tracing in One Weekend book by Peter Shirley.
The ray-tracer in it's current state generates a random scene of spheres using the current time as the seed. The scene has 3 fixed sphere to demonstrate the three implemented materials Lambertian, Metal and Dielectric; Around these 3 spheres, smaller spheres are generated randomly and are assigned random colors/materials. There are more lambertian spheres amongst the smaller spheres to reduce the complexity of the scene and time taken for rendering. The floor of the scene is a checkered pattern
The output file is in ppm as it is the easiest file format to handle which i could find. However, you can use ffmpeg to convert it into a png quite easily using
ffmpeg -i filename.ppm filename.png
For compiling
cabal build -O2
For running the executable
cabal run ray-tracer width samplesPerPixel raysPerSample
where width stands for width of image, samplesPerPixel is number of samples the program takes for each pixel and raysPerPixel is the number of rays required to compute each sample.
Camera.hs - Defines the camera object and the field of view for the image
Colors.hs - Basic Color Library written using Vectors to represent RGB
Hittable.hs - Defines all instances of Hittable objects (objects that interact with light rays) in current version of program that means Spheres and all Materials (Lambertian, Metal, Dielectric and Checkered)
I had a couple more features that i wanted to implement before submitting this, however i ran out of time and had to scrap them. I hope eventually i'll be able to come back to this project and implement most if not all of these.
- UV Mapping for custom png textures
- Rendering for other 3d shapes like cubes, cylinders etc (very close to this but intersections between different shapes would require a rewrite of how intersections are handled)
- Further Optimization; In its current naive state with very basic optimization using tips from the wiki page the code is very slow and speeds can be improved
- Custom Light Sources
- Introducing modifiable density mediums to render fogs/clouds/smoke
- Possibly look into rendering .obj files directly
- Implement motion blurring and implement ray-traced animations using frame by frame rendering
Overview:
Ray Tracing in One Weekend
Ray Tracing: The Next Week
Concurrent and Parallel Programming in Haskell by Simon Marlow
Material based rendering:
Material Shading (Reflection, Refraction and Fresnel Surfaces)
UV Mapping
Dielectric Materials
Fresnel and Beer's Law
More Theoretical and Mathematical understanding:
Course Materials from Computer Graphics (CMU 15-462/662) at CMU
Lecture notes and Course Materials from Computer Graphics (MIT 6-837) at MIT
Existential Quantifiers in Haskell
Randomness in Haskell
Generating Random points on Spheres
Time Library in Haskell
Bence Szilagyi for coding/math/general support throughout the process of writing this project.
The School of Informatics for DICE, as without them i would not be able to render any high resolution pictures.