Home

Introduction to Lighting

Distributed under the terms of the CC BY-NC-ND 4.0 License.

  1. An Introduction to Lighting in 3D Rendering
  2. Point and Spot Lights
  3. Distant Lights
  4. Area Lights: Mathematical Foundations
  5. Triangular Area Light
  6. Rectangular Area Light
  7. Spherical Area Light: Using Area Sampling
  8. Spherical Area Light: Using Cone Sampling
  9. Direct Lighting: The Light Loop
  10. Source Code (external link GitHub)

Distant Lights

Reading time: 9 mins.

Distant Light, aka the Sun

Simulating distant lights is very simple, making this chapter short. In fact, it's the simplest, most basic form of light one can implement (and probably the first type of light you implement to get something working).

But what is a distant light? In truth, true distant light doesn't exist in nature. It's a type of light where the emitted rays are parallel to each other. In the real world, most (if not all, but since I haven't traveled elsewhere in the universe, I wouldn't swear that's 100% certain) light sources have some physical shape from which light is emanating and consequently, light is generally emitted radially. Consider our sun, for instance, which is a ball of fire. Well, in ancient Greek mythology, it's seen that way. For a modern scientist, it's probably more complex than that.

Figure 1: Even though the sun is a "ball" of fire emitting light radially into the cosmos, the geometry of the sun and the earth makes it so that the light hitting the Earth from the Sun is contained in a very narrow beam, so narrow that we can approximate the light hitting the Earth to be made of light rays parallel to each other.

But the point is, the sun can be modeled as a ball emitting light in all directions. The problem is that our planet, Earth, is so far away from the sun that the light hitting our planet from the sun is contained within a very narrow beam of direction. So narrow that, at the cosmological scale, beams traveling within that cone can be considered as (almost) parallel to each other. This is essentially what the distant light in the computer graphics world is trying to achieve: simulating the effect of sunlight on Earth. And again, it might be more accurate to simulate the sun as a spherical light (which we will discuss later in this lesson). However, before the democratization of area lights, thanks to increasing computational power, we didn't bother doing so. As light rays were considered to be parallel to each other, all we needed was a direction. To keep going with the sun's analogy, you can think of it as the direction your finger points to when you orient it toward the sun to show someone where it is in the sky.

Note that some architectural software proposes to figure out the position of the sun in the sky in a physically accurate way. You input a year, a month, a day, and an hour, and the system computes the position of the sun in the sky with cosmic precision. The reason it's capable of doing so is that the equations for predicting the position of the sun with respect to Earth based on the date and time of the day have been known for centuries. What we still fail to predict is the weather on that day).

So, as you can see, all you need to simulate a distant light is a direction.

class SunLight : class Light {
public:
	Vec3<float> direction_{0,1,0}; // zenith
	Vec3<float> light_color_{1};
}

Implementation of Distant Light

From an implementation standpoint, all you need to do is shoot a shadow ray in the light's direction to determine if the point you are shading is in the shadow of some object along that direction. You can shoot that ray to infinity if you want to, where infinity here is within the context of a floating point value, that is the biggest number that a float (or double, if you decide to use doubles instead) can hold.

// origin, direction, tmin and tmax
Ray shadow_ray(x, light->direction_, 0, std::numeric_limits<float>::max());
if (!occlusion(scene, shadow_ray)) {
    L += albedo / M_PI * light->light_color_ * std::max(0.f, std::cosf(N, light->direction_));
}

As you can see with the code above, we cast a shadow ray into the scene. If there's no occlusion (occlusion returns false), then we can accumulate the contribution of this light to the overall brightness of our shaded point. If you are not familiar with the concept of light accumulation and light loops, check the last chapter of this lesson. That's it! That's really all there is to this light type.

Artistic Considerations

From an artistic or stylistic point of view, using a sunlight or not matters.

Pixar makes extensive use of such visual cues and has published over the years several articles that explain how they use lights to convey various moods in their movies. I hope to have time one day to resurrect some of these old articles and bring them to light again. The rules they explain are timeless, but unfortunately, these documents have been buried in the internet archives (Image courtesy of Pixar, from Toy Story released in 1995).

Relevance of Distant Light in Modern Rendering

As another side note, you might wonder if, with the advent of more physically-based renderers and supercomputers, using distant lights is still relevant. Why not just use very small spherical or disk-shaped area lights? This is a good question. In fact, many renderers, such as Arnold, propose a parameter on the distant light which allows you to distribute the shadow rays within a very small angle (whose value you can set, so you can experiment with different ones). Indeed, the sun is not strictly speaking a point in 3D space. From the point of view of planet Earth, it is still perceived as a small disk with a subtended angle \(\theta\) of roughly 0.5 degrees. You can easily calculate this angle by considering the distance between the Earth and the sun and the sun's diameter. So instead of placing a spherical or disk area light with a very large radius and super far away from your scene, so that it looks small from your scene point of view (and casts mostly parallel rays), which is feasible but could potentially cause errors related to floating point precision, the preferred approach is to generally distribute the shadow rays within a very small cone of direction of roughly more than 0.5 degrees. This will help you break the very sharp shadows generated by a typical distant light. Looking at outdoor scenes, you will observe that shadows all have some softness to them at the edges.

Figure 2: Most production renderers provide an angle option that allows for a more realistic effect by treating the distant light as if it were a small distant spherical light. With an angle greater than 0, the shadows get slightly blurred, similar to the shadows produced by our sun (as seen in the right image). The angle is the same as the angle \(\theta\) used in the chapter devoted to spherical light implementation using the cone sampling method.

We won't provide an implementation of the cone angle feature here, but the chapter Spherical Area Lights: Using Cone Sampling provides the explanation and source code necessary to implement it. All you need is to sample the cone of directions with an opening angle of, say, 0.5 degrees, and all information for doing so is provided in that chapter.

With this being said, this concludes our series of chapters devoted to distant lights. It's time we dive into the world of area lights.

previousnext