As part of my ongoing aim of trying to learn Haskell, I decided to take my ray-tracing experiments a step further and this time write a global illumination renderer.
The previous ray-tracing code implemented local illumination: each pixel rendered, and hence each surface drawn, has its illumination calculated completely independently of any other surface. This is fast, easy to implement, but has the downside of producing images that look pretty artificial. This series aims to implement a global illumination renderer: the light is calculated across the scene as a whole.
The first thing I needed to check was that I could actually successfully write out an image, from Haskell code.
Simple stuff first: I need a representation of an RGB value:
I need something that will generate some colors on the final image, and let me check I have vertical and horizontal orientation correct:
(So I have red increasing left-ro-right, and green increasing top-to-bottom. There will be no blue component).
For the actual writing of the image, I found Codec.BMP. (Unfortunately there doesn’t seem to be an easy way to write PNGs… I might look into it a little more at a later date, but for now BMPs will do).
The following function will write a BMP, with pixel colors determined by a rendering function that takes (x, y, w, h) values and gives a color:
Finally, I can launch the whole thing from a simple
All together, that gives me the following image:
It’s not a three-dimensional rendered scene, but as a first step I’ve shown how to write an image from Haskell.
Code is in Github, if you want to take a look.