Path tracing in Javascript using web workers
Improved version
An improved version of this path tracer is available here.
The experiment
Click to start. If it doesn't work in your browser and it's not IE or Opera, please write a comment. The output of the javascript error console would be very helpful too.
Path tracing
Path tracing is a way of solving the rendering equation using monte carlo integration. It is a form of ray tracing. According to wikipedia 'Path tracing is the simplest, most physically-accurate and slowest rendering method'. Sounds like the perfect target for a javascript experiment!
Implementation
My implementation is currently only calculating the diffuse term of the rendering equation. The only light source is the sky. The big sky speeds up the rendering and convergence quite a lot.
The sourcecode is split up into two files. main.js is the glue for initializing the workers and aggregating the results. worker.js is where you'll find the real meat. I'm spawning four workers right now to take advantage of modern multicore cpus. Feel free to ask questions if something is unclear.
Performance
As you can tell from the sourcecode it is clearly not optimized for performance. What is still interesting though is how various webbrowsers perform. On my Intel Core i7 machine google chrome (4.1) is roughly 26 times faster than firefox (3.6)! Chrome does 13 iterations/s, Firefox does 0.5. Also firefox seems to support only 3 workers, this leaves one core almost idle. The dev version of chrome is even faster at 18.75 iterations/s. My congratulations to the chrome and v8 developers. I hope firefox will catch up soon.
On a side note, I created a twitter account for those who prefer it over the rss/atom feeds.

Update
I found a little bug in the code that affected the performance. I'm now getting more than 20.5 iterations/s in chrome dev. I think a faster random function would make it even faster.

Jonas Wagner
I was trying to figure out a good way to make use of the web workers through flash, and I figured I could use the old Javascript Injection tricks to do it. However the problem I ran into was the need to pass a real external file to the Worker() constructor.. I tried a few different ways including "data:" but no luck. (in fact the spec seems to dictate that this can't be done).
Since my Javascript experience is fairly limited, I figured I would throw a comment up and see if anyone had any other ideas to pass code to the Worker() constructor, and not an external file.
I realize, that I could just make external js files, but I wanted to see if it could be done on the fly instead..
Awesome site by the way :)
Comment by Jake — 5/17/10 7:27 PM | # - re
You could just send the code in via postMessage() and then eval() it in the worker. Or am I missing something?
Comment by Jonas Wagner — 5/17/10 7:38 PM | # - re
Haha, there is a good chance that I am the one that is missing something...
So I guess the end result I would like is to be able to do this: var worker = new Worker("postMessage({result:"test"});
worker.onmessge = function(e)
{
console.log(e.data.result);
}
So I'm not sure how to define the code that goes in the worker without passing in a link to an external .js file. Essentially I would like to be able to define the worker contents inline without going external for the data. So I guess I'm not sure on how to create a worker without passing in a valid link to an external .js file...
I have a feeling I'm not being very clear, I can try to put together an example if you are still interested..
Thanks very much for the reply!
Comment by Jake — 5/18/10 3:21 AM | # - re
Ah I think I understand your problem now. From reading the spec I don't think it is possible to work around this. If you want to get creative you could try to create a swf file that can be interpreted as javascript at the same time. ;)
Comment by Jonas Wagner — 5/18/10 11:51 PM | # - re