Archive for the 'C++' Category
Direct3D 11 Multithreading
I’ve been putting it off for a while, but with my recent trip to GDC and the arrival of the Direct3D 11 beta, I thought it was about time I switched my renderer to be multithreaded. One of the things I learned at a Direct3D 11 talk at GDC is that it works on ‘down-level hardware’, which means DirectX 9 & 10 cards. Of course, you don’t get the snazzy new hardware features, but you do get some of the benefits of the new API, like multithreading and limited compute shaders (albeit not as fast as it will be on the real hardware).
Read more
Irradiance Caching: Part 1
Solving the rendering equation with even just one bounce of indirect lighting can take a long time. The majority of time spent rendering a frame is in estimating the lighting integral. For example, rendering a single bounce of indirect lighting at 720p resolution with 256 sample rays for a Monte Carlo estimator requires about 237 million rays to be cast. This doesn’t even include the rays needed for sampling the lights for direct lighting, so in practice, the total will be even higher.
One interesting observation made by Greg Ward in his Siggraph ’88 paper is that contrary to direct lighting, where shadows and lights can cause harsh changes, the indirect lighting on a surface tends to vary relatively slowly. One way to picture why this is, is to imagine the computing average color from the what you can see from each of your eyes. Even though each eye has a slightly different view on the world, the images they see are nearly similar, and so the average color is also nearly the same.
3 commentsMockItNow: Throwing Exceptions
I’ve made a small update to MockItNow to allow you to throw exceptions when replaying function calls. You basically record the function call as normal, and provide the exception object that you want to throw during the replay using the EXPECT_THROW macro. You can also make a function default to throwing an exception at registration time using REGISTER_THROW.
If you want to see a couple of examples of this feature, take a look at the bottom of the sample file here.
No commentsBetter Sampling
A couple of days ago, I compared the images my ambient occlusion integrator produced with those of Modo using similar settings. I noticed immediately how much ‘cleaner’ the render from Modo was. Clearly there was an issue with the way I was picking my samples, so I set about improving things.
My approach for generating the ambient occlusion rays was to generate uniform random samples over the hemisphere about the normal. Based on two random numbers in the range [0,1), I calculate the normalized sample direction using the following function:
Vector3 Sample::UniformSampleHemisphere(float u1, float u2)
{
const float r = Sqrt(1.0f - u1 * u1);
const float phi = 2 * kPi * u2;
return Vector3(Cos(phi) * r, Sin(phi) * r, u1);
}
This generates points on a hemisphere from uniform variables u1 and u2, where each point has equal probability of being selected. The following image was generated with 256 random uniform samples:

The Holidays: Time for fun work!
For the first time in about three years, I’ve had two weeks off work. I’ve spent a lot of time just relaxing and taking a break from things, but I’ve also been able to get back to doing some graphics work. Ever since Vivendi bought Activision, the project that I was leading has been “put on hold”, so I’ve been back on the game team. It’s not as fun for me, that’s for sure, but luckily, I have my code at home to play with, so all is not lost! With the holidays, I’ve found some motivation to get back to it.
What have I been doing? Well, as I was approaching the break, I read through the course notes from the Practical Global Illumination with Irradiance Caching course at Siggraph last year. I thought the course itself was really good, and very clearly presented. After blitzing through the notes again, I thought I’d have a go at writing a ray tracer. It seemed simple enough at the time, but like most things, the devil is in the details.
The first thing I did was to set up a really simple single-threaded ray tracer that just displayed the color of the surface it hit. This was fairly quick to get up and running once I had written a few supporting classes for the cameras and shapes. It’s not very glamorous, but it’s a start:
2 commentsMinor Update to MockItNow
This is just a quick note to say that I’ve updated MockItNow on Google Code to allow you to define storage types on a per-class basis using the DECLARE_STORAGE_TYPE macro. I did this so that the Mocker can deal with abstract class parameters. Please note that the macro must be declared at global scope because it uses partial template specialization.
I updated the download, and the source. You can see the new test at the end of the file here, and the only other affected file is Storage.h.
Thanks to Lance for pointing this problem out.
No comments
