🔒 Locked
Ambient Occlusion raytraced
Advertisement
Original Post
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!
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.
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.
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.
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).
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.
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.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement