Friday, October 5, 2012

Sampling the Sun Directly

The sun covers only a tiny fraction of the sky, about 0.00047%, so with naive path tracing, most rays would get lost in space and the image would take forever to converge. By sampling the Sun directly, I was able to speed up my simulation tremendously. At each scattering point, I fire a ray directly towards the Sun, weighted by the Rayleigh scattering phase function in that direction, and weighted by the probability that a ray fired in a random direction would hit the sun. I also still fire a scattered ray in a direction drawn from the Rayleigh scattering phase function, however this ray cannot "see" the Sun. If I were to only sample the Sun, I would lose multiple scattering, which plays an important role in the appearance of the sky. For computing sample directions that are uniformly distributed over the solid angle subtended by the Sun (the Sun is not a point light or a directional light), I used the Sun class that I wrote for Photorealizer.

2 comments:

  1. Hi Peter,

    how do you sample the solid angle subtended by the sun?

    Also, since the sun is so far away, I guess the directions of lightrays will be very similar. I wonder if there is any noticeable difference when modelling the sun as an area light as opposed to a directional light.

    Cheers,
    David

    ReplyDelete
    Replies
    1. Hi David,

      Here's how I sample the solid angle subtended by the sun. First, note that one way to generate a random direction in the full sphere of directions (or, equivalently, pick a random point on the surface of the unit sphere) is to choose a random cosine of the inclination angle from −1 to 1, and a random azimuth angle from 0 to 2π. Now imagine if the sun were straight above, at the zenith, and you knew the angular diameter (visual angle) of the sun. Then, sampling the solid angle subtended by the sun would be the same as sampling a direction in the full sphere, except instead of choosing a random inclination angle from −1 to 1, you would choose a random inclination angle from cos(half the sun's angular diameter) to 1. You could then get the xyz components of this sampled direction by using the sampled cosine of the inclination angle as your z coordinate, and then using a little trig to find the x and y coordinates, based on the sine of the inclination angle and the sine and cosine of the azimuth angle (note that you don't need to compute the actual inclination angle to find its sine—you can just use the fact that sin^2 = 1 − cos^2). For a sun in an arbitrary direction, you just need to transform these coordinates to align with that sun direction, which you can do using the sun direction and two perpendicular vectors.

      True, the light rays from the sun are nearly parallel, and treating the sun as a directional light probably wouldn't make much difference to the appearance of the sky overall. I haven't tested it yet to be sure, but if anything I think it could potentially affect the sharpness of the Earth shadow, or the appearance of the sky when the sun is straddling the horizon (although the behavior near the horizon isn't completely accurate anyway because I'm not considering refraction), or the appearance of the sky very close to the sun. And of course, it's nice to be able to see the disc of the sun. For rendering in general, I think modeling the sun as an area light is pretty important. This gives shadows penumbras, instead of perfectly sharp edges. With increasing distance from the object casting the shadow, the soft edges of the shadow become increasingly noticeable. And giving the sun area allows it to appear in reflections without it necessarily being sampled directly.

      Peter

      Delete