16th December 2005
The return of the bathroom scene. Render time: ~46000 secs. Unlike the other render of the bathroom down the page, this one is using the totally unbiased Monte-Carlo spectral Metropolis tracer. I fixed a stupid bug a couple of days ago that has resulted in like a 3x speedup in the render time, meaning I can now render these scenes without too much noise. This render actually stopped after the 32 bit signed integer mutation counter wrapped around, eg after 2.14 billion mutations :) The next thing i need to do is add in some kind of skylight model, so I can have a nice sun beam coming in the window :) Now that i understand how multiple importance sampling works, this shouldn't be too hard.
11th December 2005
I added a material override system, so that I can load up .3ds models, but specify the material to use for each material that was in the .3ds file. The overridden materials are specified in the scene xml file, and look something like this:
<matoverride matname="teapots"> <phong> <diffuse>0 0 0</diffuse> <specular>0.8 0.8 0.8</specular> <exponent>100</exponent> </phong> </matoverride>
A render using the new system: Spectral Metropolis L.T. tracer. Render time ~50000 secs. Materials: The wall is a Lambertian (diffuse) reflector with reflectivity 0.8. The teapots are an isotropic Phong material. The floor and steps are an isotropic phong material with a diffuse wood-textured substrate. Model graciously provided by Hao La.
Sibenik Cathedral, render time ~30 hours. Spectral Metropolis L.T. All materials are isotropic Phong with exponent 100. No texturing or normal smoothing, oops :)
30th November 2005
Yeah, what I was gonna say about the render of the glass below is that I need to use something like multiple importance sampling, which is implemented now. Veach and Guibas wrote this paper on it in '95: Optimally Combining Sampling Techniques for Monte Carlo Rendering. It's helpful for situations like at the ground near the bottom of the light sources in the two images below, where sampling of the light surfaces as opposed to sampling the bsdf of the ground becomes very inefficient. This problem manifests itself in the glass render as noise at the bottom of the light sources. (/me wonders if that made sense at all :))
~20 mins, spectral MLT with multiple importance sampling:
18th November 2005
More info on this pic laterz!!11!
14th November 2005
... A tap! Render time: ~60000 secs. Spectral Metropolis LT. The tap uses an isotropic phong material.
10th November 2005
Finally got Metropolis light transport (MLT) ray tracing going decently. It's based on the original paper by Veach and Guibas, but using the beautifully elegant mutation scheme of Kelemen, Szirmay-Kalos, Antal, and Csonka, described in A Simple and Robust Mutation Strategy for the Metropolis Light Transport Algorithm.
Right now it's still using standard path-tracing as a base path generation technique, as oppposed to bi-directional path-tracing. Convergence times are similar to straight path-tracing right now, for most scenes. But it's early days yet, there's bi-directional path tracing to add, and I need to find some way of using low-discrepancy sampling such as stratified sampling effectively.
Oh, and as a side note, just a reminder to *never* allocate memory from the heap inside your inner graphics loops. I was creating a std::vector on the stack every mutation, then i changed it to a member variable to avoid the alloc and free each mutation, and immediately got a 2x increase in overall execution speed :)
Render time: 74953 seconds (~= 20 hours), some obscenely large amount of mutations per pixel, dunno exactly how many 'cause the mutation counter overflowed and wrapped around :)
19th October 2005
This is a test image from my new spectral renderer. Instead of each ray having a RGB triplet of radiances, each ray has a radiance for a single wavelength, where the wavelength is randomly selected from a range that is usually about that of the visible wavelengths, eg 400-700nm. The light source in this image has been modified to procedurally emit different wavelengths along its width, from 360nm on the left to 860nm on the right, with a spectral peak width of 20nm.
So when a ray is spawned, a particular wavelength is chosen, and the ray bounces around the scene. The final RGB contribution of the ray is calculated by mapping the (wavelength, radiance) pair to XYZ colour using the CIE XYZ curves, then linearly transforming the XYZ colour to RGB colour.
Dispersive refraction (different indices of refraction at different wavelengths) is implemented, but its effects are not visible in this image.
16th October 2005
render time: 13697 seconds, 2500 samples per pixel.
20th September 2005
Hacked up camera lens chromatic aberration as a post-process effect. Fundamentally limited while I'm still just using RGB spectrum representation. Looks kinda cool tho. This effect is achieved by moving the red and blue RGB components radially a little bit.
Render time: 8711.681116 seconds, DOF, 1600 samples per pixel, Monte-carlo path tracing, env light and one area light, tonemapping:
14th September 2005
And another one, this time with DOF. Render time: 4554 seconds, 1600 samples per pixel.
14th September 2005
I was quite suprised this one came out so well, considering it's just the plain old Monte-Carlo path-tracer in action. I guess the reason it could be done at all in a reasonable time is that there is a big area light and background light. Model from here.
Render time: 2961 seconds, 1600 samples per pixel.
Also some new results for the Ray/Tri benchmark.
8th September 2005
Straight path-tracing, Ashikhmin and Shirley isotropic Phong model on the ring, Ashikhmin and Shirley isotropic Phong model with diffuse substrate on the wood plane, depth of field, constant environment light, and one area light. 6400 samples per pixel, render time 10400 seconds.
5th September 2005
So this image has a few artifacts in it but it's gonna take a while to smooth them out so I'd thought I'd post something anyway. Added quite a lot of new stuff, the first being explicit sampling of triangle-meshes as light sources. The light source in this scene is the 2 triangles making up the window. I also implemented Ashikhmin and Shirley's Anisotropic Phong Model. The Isotropic version of it is used for the metal fixtures below. The other materials are Lambertian reflectors. For these I'm using a crazy new technique that I call image-space irradiance filtering, inspired from this paper: Irradiance Filtering for Monte Carlo Ray Tracing. You can see what the image-space filter kernel looks like from looking at the large orange dot in the image below :)
Render time: 5201 seconds, with final gathering, image-space irradiance filtering, 900 samples per pixel. Thanks to Claudio for the neat scene.
24th August 2005
I put up a little info and some intermediate images from the final gathering render below here.
23rd August 2005
This image was rendered using final gathering photon mapping for the indirect illumination. If I had some more web-space i'd chuck up some of the intermediate stages of the render :P. Render time was 80 mins, 400 gather rays per pixel (old image: Render time was about 20 mins. 100 gather rays per pixel.)
14th August 2005
Found a place to get some nice free material maps: xyzRGB. The Image below has a material with diffuse, specular, and normal maps. It's the 'masonry' material from the site. Image below took ~30 mins, with my path-tracer using stratifed sampling, with 2500 paths per pixel. Oh yeah, the sucky thing about xyzRGB's maps is that they don't tile :(
18th July 2005
Variation on the 3 spheres theme. 3204 seconds, 60x60 grid = 3600 samples/pixel
13th July 2005
So I've got stratified sampling working pretty nicely. In the image below, the lens positions (for DOF), points on the area light source, and points on the hemisphere for indirect illumination are all sampled using stratified sampling. This allows me to get a nearly noise-free image in 40 mins or so. The stratified sampling is done with a 50x50 grid in the image below, meaning there are 2500 samples per pixel.
The anti-aliasing via supersampling was turned off in this pic leading to the jaggies on the upper edge of the sphere :(
27th June 2005
Hmmm thought I should update this page... I've been working on a distributed 'realtime' ray-tracer. Here are some screens from it. This is with just one slave node running. Ideally the FPS should scale linearly with the number of nodes. In practice it's kinda tricky :)
Stuff in the screens: direct lighting, one directional light source. HDR .exr enviromenment map. Fresnel diffuse/specular material on the plane. 69000 tri plane model.
22nd May 2005
This one has a ludicrous 40000 primary rays per pixel. DOF, kitchen probe, etc.. etc.. Took about 11 hours to render. Pure Monte-Carlo.
The difficulties I was having rendering the Martini glass image a few down that I alluded to were to do with massive amounts of total internal reflection. I'm treating total internal reflection correctly in my tracer, by bouncing the ray back inside the medium when the angle of incidence at the interface exceeds the critical angle. What was happening is that rays from the camera were hitting the rim of the glass and being refracted into the wall of the glass. Because the critical angle inside the glass is fairly high, and the wall of the glass is fairly thin, rays were being totally internally reflected back and forth along the wall of the glass - the wall of the glass was acting as a waveguide :) This was in turn was exceeding the capacity of my tracer to deal with such a large number of internal bounces: I was getting stack overflows, or all the rays were being russian-roullette killed etc..
18th May 2005
Resurrected the photon mapping code plus some other stuff:
Whereas this one's pure Monte-Carlo:
11th May 2005
I may write some more tomorrow about the many problems encountered while rendering this :)
Render time: Approx 5hrs on 2 computers, approx 2000 primary rays per pixel. Pure monte-carlo tracing. Uses the kitchen HDR probe. Martini glass is ~5000 tris.
9th May 2005
The cool thing about the image below, apart from the classy kitchen probe, is that it was generated by 3 computers running a parallelised version of my renderer. It works in a pretty simple way; the rendering task is divided up into slices which are passed out to slave processes on the hosts. The slaves just send back the image slices.
28th April 2005
27th April 2005
Some metal materials with varying glossiness. These are done by using a non white-specular colour.
27th April 2005
render time: 40801.097431 seconds.
approx 1000 primary rays per pixel.
4992 tris per martini glass.
After this series.
25th April 2005
So I decided that I wanted to test my ray tracer on a more realistic indoor scene. I had a nice pic which i picked up on deviant art, so I modelled something vaguely similar to it in 3dsMax. After fixing a bug in my kd-tree code, and after an all night render, here's the result:
Its got full global illumination, done purely with Monte-Carlo tracing (no photon maps). = Very Slow. There are two light sources: a small area light off to the right of the building, and a spherical 'background' light source.
Btw, if there are any modellers out there who want to collaborate on building a scene like this, but with better textures, like with full normal maps, specular maps etc... get in contact with me.
24th April 2005
20th April 2005
So I finally got anti-aliasing working properly. Turns out it was interacting badly with the supersampling and adaptive sampling code because I was clipping the sub-pixel intensities too early and more than once :) This was causing an odd artifact where high-variance areas were coming out too dim.
You can see the new glossy reflection code in action below: Its done in a kind of hackish way: I'm purturbing the reflected ray directions with a quick Gaussian-ish distribution generated by adding 5 small random vectors, scaled by the glossiness of the surface. The ray dir is then renormalised and made sure it is not pointing into the surface.
15th April 2005
Added smoothed normals to the ray tracer. Also added back in clamping of sub-pixel intensities before summing them together. This means that stuff like the edges of lights are nice and anti-aliased as u can see below.
13th April 2005
Trebuchet MS. Word.
29th March 2005
28th March 2005
The new C++ profiler, complete with wxWindows GUI, is now up at http://sleepy.sourceforge.net/ I've spent the last few days wrestling with CVS and sourceforge, hopefully things are working well enough now.
26th March 2005
Hacked in texturing, just for planes at this stage, which is a ridiculously easy hack. Also added some kind of specular lobe reflection thing (glossy reflections).
5th March 2005
Updated the Ray/Tri mesh intersection benchmark with some new results.
3rd March 2005
Released the src for my new Win32 C++ profiler. Check it out, it r0x0rs!
10 Feb 2005
You can grab a giant 1000x1000 version of the above image in PNG format here
8 Feb 2005
All your sphere are belong to us:
So I split up the site so my connection doesn't get so hammered on visits to this page. Been working on a couple of things on my raytracer. Finally taking out scene hard-coding - i'm doing an xml scene loader. Fairly pain free so far. Using TinyXML as per usual.
Added in something that is perhaps called adaptive sampling? Basically, for each pixel, I run say 8 copies of the renderer in parallel. Something like the variance in the pixel colour can be computed, giving an estimate of the accuracy of the computation so far. Sampling of the pixel is stopped when the 'variance' falls below a certain threshold. This technique doesn't so much eliminate noise as transmute it into a new and exotic type of noise which occurs when all 8 copies miss some important part of the hemisphere. However crank up the minimum number of samples enough and you can get good results, for example:
render time: 793.221660 seconds
min num primary rays/pixel: 160.
The actual number of rays shot depends on the noisyness at that pixel.
19 Jan 2005
Haven't been doing any coding 'cause of WoW. The only reason I'm updating this page is cause the servers are down :P.
Below is a pic of a horde raid into the auction house in Ironforge which I thought was kinda funny. About a hundred people in one tiny room. Needless to say the lag sucked. You can also see why the servers don't try and do inter-person collision detection.
20 Dec 2004
I'm pretty happy with this image. Just.. a.. few.. artifacts.. left.. to.. kill. Note the smooooth caustics from such a little light, and with just 800 rays per pixel.
render time: 543.390295 seconds
primary rays per pixel: 800
Reflective caustics, done with photon mapping.
render time: 1693.023609 seconds
primary rays per pixel: 1600
1M photons traced (but not all used) for the photon map.
I did a bit of work on speeding up the photon map lookup but it's still kinda slow.
19 Dec 2004
Hacked in photon mapping. Here's a preliminary render:
render time: 883.950762 seconds
primary rays per pixel: 160
The photon map is used to render the caustic; everything else is done with the usual Monte-Carlo ray tracing. 100000 photons were shot, but only the caustic photons were recorded. I'm using a cone filter on the photon map right now. The main thing to note here is the smooth caustic with only 160 samples (and it would be smooth with 1 sample as well). Unfortunately right now the photon map lookup is really really slow, so I could only do 160 samples/pixel in a reasonable time. So yeah, the new bottleneck is photon map radiance lookup.
2 Dec 2004
I modelled this one after a glass lying around the house. 30800 tris. I plan to take a photo of the real thing soon so I can see the differences :)
render time: 2160.162914 seconds
primary rays per pixel: 3200
A rehash of the sphere caustic pic, this time with interior reflections on the sphere and DOF. I fixed the DOF effect; not every primary ray was being peturbed. It's a lot smoother now.
render time: 886.768357 seconds
primary rays per pixel: 3200
29 Nov 2004
One of the stranger renders i've produced:
render time: 2931.448054 seconds
primary rays per pixel: 1600
This is what the sphere looks like with multiple internal reflections. Mmmm so pretty.
render time: 786.682971 seconds
primary rays per pixel: 3200
I discovered a good debugging test for GI tracers with transparent objects: draw a totally transparent object with a refractive index of 1. If you can see it, you fucked up :). Actually you get a wierd effect with russian roulette ray termination which is that the regions around the 'invisible' sphere are noisier than elsewhere, so you can actually make out the sphere :).
I think I have figured out why my anti-aliasing is failing around sharp highlights like the area light reflection in the sphere above.. I think i need to take the average of the samples after clipping the components to [0, 1]. Damn, what a hassle.
27 Nov 2004
Image-based-lighting caustics. Yes, the green artifacts are in the original environment map. This image has an obscene amount of noise, even with so many samples, due to the teency-weency little lights in the env-map.
render time: 3556.578135 seconds
primary rays per pixel: 6400
Finally summoned the motivation to add transparency to my Monte-Carlo ray tracer. Still not finished, need to add multiple internal bounces. Also check that all the maths is alright.
render time: 482.853241 seconds
primary rays per pixel: 1600
23 Nov 2004
Updated the benchmark page yet again with some new vec gen code and other stuff.
19th Nov 2004
Ok, I can do mr hi res, 1M tri Happy Buddha now. In this render the happy Buddha is at the beach. The beach probe is a nice one for fast renders as it has a large bright sky area -> less variance.
primary rays / pixel: 1600, 883.701725 seconds (plus tree building time)
render time: 677.482062 seconds, primary rays per pixel: 1600
Mr Happy Buddha. My engine can't quite handle the full 1 Million tri Buddha right now, so this is the 293K tri version. 5760 seconds, 3200 primary rays / pixel.
18th Nov 2004
Slightly excessive DOF on this one. 1600 primary rays/pixel, 1200 secs.
The benchmark page has been updated a bit with some new debugging info and my new results.
16th Nov 2004
Kind of a boring pic this one.. the bunny yet again, the hi-res 69000 tri version. All surfaces in this pic are Lambertian. 2798 secs, 320 primary rays / pixel. My kd-tree code is getting a bit faster, up from 12K rays/sec to 63K rays/sec in my benchmark. And there's still a long way to go.
15th Nov 2004
Posted a page on a benchmark for testing ray/mesh intersection speed. May come in useful if you wanna see just how fast (or slow:P ) your shiny new kd-tree or BVH is.
14th Nov 2004
1700 secs, 3200 primary rays/pixel. I hacked caustics out of the equation in this pic, as the white dots it produces are really difficult to get rid of by just using more samples. You may also notice that the camera can now assume arbitrary orientations :) This pic also has depth of field and a Fresnel term on the spheres. Btw, when I refer to caustics I mean a photon that conceptually follows a light src -> 1 or more specular reflections -> diffuse reflection -> camera path. Of course in normal ray tracing u trace the ray in the reverse direction along the path.
The return of the spheres and the cathedral probe. This time with Fresnel term and depth of field. 1500 secs, 3200 primary rays/pixel.
13th Nov 2004
Hooked up my 3ds loading code to my Monte-carlo ray tracer. This torus knot render took 2000 secs. 320 primary rays/pixel. Damn I really have to get some renders not using this stupid Cornell box :)
12th Nov 2004
Return of mr Bunny Rabbit, lo res version this time. 866 secs, 160 primary rays/pixel.
11th Nov 2004
Monte-carlo renderer in action with the kd-tree code. The Stanford bunny pictured is 69000 tris. Sadly this render took 1.3 hours :P. Still a lot more hacking to do on the kd-tree code :). 36 primary rays per pixel.
Put up some Ply mesh loading code in the code section.
11th Nov 2004
Monte-Carlo rendering, 307 seconds, 1600 primary rays/pixel. Mmmmn Sexy.
8th Nov 2004
Shot from the lightmapper I'm working on. It's very basic at this stage - lame regular-grid auto UV generation and Phong lighting (without the specular term of course). Ray/Mesh intersection is sped up with a KD-tree. KD-trees are very cool, fairly simple to construct, and ray traversal is very simple and fast. Check out this thesis, Heuristic Ray Shooting Algorithms (Vlastimil Havran, 2000) for a good overview of KD-trees.
28th October 2004
JSpace snap: more info on the pic here.
25th October 2004
Fist release of JSpace, a client-server version of my Digital Sunlite Project. I highly recommend you check it out.
7th October 2004
Posted something about hypercards and stuff here.
26th August 2004
Finally put up my realtime radiosity demo:
15th August 2004
Added some graphics links to the links section.
13th August 2004
Everyone's favourite special effect: reflective water that reflects local objects! :) This effect is done by reflecting the camera orientation and position in the water to get the transform of a 'virtual camera'. The scene is then rendered from the virtual camera's point of view, into a pbuffer target. The pbuffer is then bound as a texture. Reflected eye rays are calced in a GLSL fragment shader, using sine-perturbed normals, and used to look up the pbuffer texture. Its actually quite a hacky effect, cause it's effectively doing environment mapping, using only the reflection vector. This is fine for far objects, but totally incorrect for near objects, as it doesn't take into account positions. Still it looks pretty good. I also need a way of clipping away submerged tris when doing the reflected scene render, hopefully I can do this in hardware.
9th August 2004
Finally got hardware shadow mapping going really well. It was an absolute mission. Whole thing is done in only 2 passes, 1 to get the shadow, the second to apply the shadow to the scene and to render the scene. A Fragment shader is used to work out the lighting using the depth comparison value. Unfortunately, the optimal method needs a Nvidia only extension, NV_render_depth_texture. Oh well. There's even some antialiasing by multisampling of the depth texture used in the fragment shader :)
7th August 2004
Been messing round with GLSL shaders. Whipped up a water effect:
Normals are generated per pixel, by adding together 3 sin waves which move with time. A reflection vector is calculated by reflected the eye-to-pixel vector using the normal. The reflection vector is used to lookup a colour from a cubic environment map. There's also a Fresnel term which modulates the opacity, but it's not really visible in this pic.
Btw, GLSL (OpenGL Shading Language) is really cool, it has a nice terse C/C++ syntax and is nice and high level.
21 July 2004
More image based lighting, using high dynamic range(HDR) images. Probably the coolest thing about HDR maps is the reflection effect you get on objects with just a bit of specular reflection, such as the plane and right sphere in this image:
Oh and the tracer has a simple griddy-thing anti-aliasing scheme now. Image was rendering in 274 seconds, 1600 samples per surface point for the diffuse reflection.
21 July 2004
Image based lighting, yay!:
I'll post some more info on this technique later.
16 July 2004
More Monte Carlo goodness:
14 July 2004
A rendering from the monte carlo ray tracer I'm working on:
Took an hour or so to render it. It's got a bloom filter using a Gaussian kernel on it, as well as gamma correction. Absolutely no importance sampling on it, which is only feasible in scenes with giant area lights :) (or point lights). The reflecting ball has reflectivity 0.5.
I'm sure you'll agree with me that Monte Carlo raytracing fucking rules.
21 June 2004
Internet Connection Firewall Does Not Filter or Provide Firewall Services During Startup and Shutdown. Bwahaha.
21 May 2004:
New version v1.2.0 of my cyberspace released.
6 May 2004:
Posted a bit about a glow effect here.
21/4/04: Got the Visual C++ Toolkit 2003, the free console mode compiler and linker( the optimsing version), from MSVC .net. Finally managed to get the MSVC++ 6 IDE pointing at cl.exe and link.exe and the c runtime libs. I also finally figured out how FUCKING SLOW the non-optimising compiler is compared to the optimising version. The simple ray tracer runs at 2.7 fps with the msvc++ 6.0 compiler, and 6.2 fps with the new one :) . So i gotta get the pro edition with the optimising compiler soon. Unfortunatly the new compiler produces different debug info, so u can't debug your programs using the old IDE. Damn. But I may use it for final versions of my code.
--Nick Chapman, email@example.com