Sign in to follow this  
solinent

Ambient Occlusion raytraced

Recommended Posts

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!

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this