February 9th, 2008
Reaching the result of the last image took me about two days. It's also my first program written entirely with Emacs, so there was a little C-M-S-whatever fighting but it was really worth learning.
First image - after almost a day of coding:

15 seconds rendering time, about 500 lines of code and... well, it looks exactly as a flag of my nationality... (It's an infinite, horizontal, red plane).
The same day rendering improved a bit more:

And more...



Reaching finally:

Next day work went just a little bit forward, I corrected mistakes in calculations of diffuse lightening, removed artifacts, added simple anti-aliasing, voilla:

Variation of previous picture:

At last, nearly finished. Specular, diffuse, ambient and reflected lightening in place!

Still no refraction... and no texture support. If I won't get bored too soon I guess I'll add some of this features. And hence I can create a little road map for C++ version.
Two days later...
Code rewritten, refraction seems to more/less work, simple functional textures and texture mapping is done. There are for sure minor things to correct in lightening model, and plane mapping.
Texturing:

Refraction:



Another refraction example:

Summary given for the last rendering is as follows:
(1233284 main rays) (0 reflect) (1578544 refract) (61606006 shadow rays) traced = 64417834 in 522.00 seconds
So it took 8.7 minutes to trace 64 millions rays... I guess it would at least triple with reflections.
Code under GNU GPL3 license can be seen here:
highlighted version and pure source version: raytracer.ml
It's 900 lines without functions generating scenes (and 1267 with them). Not so big.
This is a mail of my good friend who loves rubbish email. Send him some if you want to land on my not-so-welcome lists: John Sparrow john@thera.be john(at)thera.be
Static pages
Tags
Newest articles
Recently updated
External links
Comment by lambda ninja
submitted on February 12th, 2008 at 21:07
Well done! ;)
Comment by Marcin
submitted on February 13th, 2008 at 17:20
Niezle Tomku :)
Comment by Jon Harrop
submitted on March 28th, 2008 at 17:09
Great program!
Only takes 335s on my dual core 4400+ AMD64. Your "collide" function is very slow though, e.g. reallocating the accumulator at every step unnecessarily. Just optimizing it a bit brings the time down to 199s on my machine:
let minimal_distance = 0.00001 in
let vx = s.center.Vect.x -. ray_start.Vect.x in
let vy = s.center.Vect.y -. ray_start.Vect.y in
let vz = s.center.Vect.z -. ray_start.Vect.z in
let dx = ray_dir.Vect.x in
let dy = ray_dir.Vect.y in
let dz = ray_dir.Vect.z in
let r = s.radius in
let v' = vx *. vx +. vy *. vy +. vz *. vz in
let d' = dx *. dx +. dy *. dy +. dz *. dz in
let a = 2.0 *. (vx *. dx +. vy *. dy +. vz *. dz) in
let delta = a *. a -. 4.0 *. d' *. (v' -. r *. r) in
if delta minimal_distance then
if second minimal_distance then second else infinity in
if t >= best_t then collision else
let opacity' = 1.0 -.
(Material.get_property
~material:(get_object_material obj)
~property:`TRANSPARENCY) in
t, sphere, opacity +. opacity'
Add a comment [+] Hide the comment form [-]