Ambient Occlusion raytraced

Started by
8 comments, last by crowley9 15 years, 11 months ago
I bet this is simple, since it isn't described anywhere I can find with google, but I want to implement ambient occlusion using raytracing (in a raytracer) in order to better understand graphics programming. Anyways, how does one go about generating a random ray about a normal (to calculate the occlusion factor)? I could use trigonometry, but I'm sure there's a better way. Thanks!
Advertisement
1) Generate a random vector in the [-1,1]x[-1,1]x[-1,1] cube.
2) If it is outside of the unit sphere, reject it. If it is inside the unit sphere, normalize it so that it is on the surface of the unit sphere.
3) Dot it against the normal of your desired hemisphere. If the result is positive, then use that vector. If it is negative, then negate the vector and use that.

There are other ways to do this directly (and you probably actually want a cosine distribution since you are using this for illumination), but this is the easiest way to generate rays with a uniform distribution.
Thanks, I'll try that out.

I haven't taken any linear algebra courses, I'm still in high school, so I am basically winging it.

It makes sense, except for the part about rejecting it if it doesn't lie in the unit cube.

Dotting it with the normal tells me if it lies within the hemisphere, and this is what I looking for.

However, a random ray from -1,1 in all dimensions that is normalized will always lie in the unit sphere around the origin, right?

Anyways, thanks, you've put me on track now.
Yes, normalizing will map all the values onto the unit sphere surface, but you need to reject samples that land up outside the unit sphere, otherwise you will land up with a non-uniform distribution, where you get more samples around the diagonal axes.
Oh, ok, that makes some sense.

I'll implement it and be right back :)

(so I should normalize the randomized value, and ensure that the x, y and z values of the randomized version are more or equal to the normalized version)
Or you could use the method described here: http://www.cgafaq.info/wiki/Random_Points_On_Sphere
In my ray tracer, I precalculate a set of points on a sphere with uniform distribution. When I want to cast a ray in a random direction, I pick a random point from that set, and negate it if the dot with the surface normal is negative. This gives me a correct vector, with almost perfect uniform distribution, in very little time.
My method is similar to the phantomus one, but I'm precalculating set of points stochaistically (pretty nice results - much more randomness, but it's not that hard to switch to uniform distribution).

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

Great, here's a pic of my AO, with the first method described:
(There seems to be a problem: the edge where the two planes meet should look darker)
http://img104.imageshack.us/img104/5336/renderzd7.png
Are you scaling your rays by the cosine of the angle between them and the normal? The irradiance of a surface patch (or differential surface patch when you consider only a point) wrt. an input direction is proportional to this.

For performance it is also possible to directly generate points in a distribution that accounts for this (cosine distribution), which will save the cosine and a bunch of ray casts, and allow you to store the the distribution in a precomputed table, like others have mentioned. I suggest just applying the cosine factor to each of your rays first.

This topic is closed to new replies.

Advertisement