Carlos Lemos explained what light is, discussed what to think about when working with lighting, and talked about the characteristics of shadow.
What is Light?
If we want to learn how to replicate light, we should know how light works in the real world.
The thing is, it’s too complicated. If we tried to replicate it exactly, it would take way too much time, so the general approach is to look for a way to get a good enough result by analyzing the different effects that form lighting, decomposing them into parts and combining them to get a good enough result.
In this article, I will try to summarize these effects and study a bit of them, so that we understand how they work and improve how we render things. I will also try to keep it simple and talk about we approach lighting in non-realtime CGI, real-time CGI, and illustration so everybody can get something from it.
Let’s consider light as a series of rays (it isn’t, but it's close enough for what we need). Light sources emit rays that scatter through the world. When those rays reach our eyes, we see the light reflecting off those objects. Based on this behaviour, we can define emission (light gets emitted from a light source), reflection (light bounces from objects), transmission (light goes through an object), and absorption (light gets absorbed by an object, heating up).
Light gets emitted from a light source when that source is at a high energy state and emits light in order to get into a lower energy state.
In most cases, emission comes from incandescence: we charge a substance with electrical energy, and it releases the energy as light, but there are other sources (blackbody radiation, fluorescence, phosphorescence, particle acceleration, radioactive decay, lasers, fire, etc.)
Visually, light sources are very similar and they usually only change in intensity and color, not how they interact with matter.
In this scene, we have: a floor, a sphere that is emitting light towards the floor, and a white light.
Light can bounce from the object, giving us reflected light. We separate reflected light into 2 different types of reflections:
- Diffuse Reflection: the ray of light can penetrate slightly the surface of the object, interacting with its molecules and bouncing back in a random direction. Since the light interacts with the object intensely, some part of it gets absorbed, and the reflected light is colored. Most of the reflections in a material work like this.
- Specular reflection: light can bounce back at a perfect angle and go towards the viewer creating a specular reflection. Since the light interacts very briefly with the object, specular reflections usually keep the color of the light source ignoring the color of the object.
If the ray of light can go through the object, we will get some effects such as:
- Transparency: the ray of light goes through the object and its direction is unchanged. This is what happens in real life with most gasses.
- Translucency: because light can travel at different speeds depending on the medium it’s passing through, when it passes through many different mediums with different properties, it appears to bend. This is what happens in real life with water, glass, etc.
The relative speed at which light travels through a material is called the index of refraction of that material. Refraction can also cause other effects, such as rainbows, caustics, or prisms.
- Subsurface Scattering: a translucent object might receive light, which interacts with the object intensely (getting colored) and bounces back out of the object making the object look emissive, especially on thin surfaces where it is more likely for light to go through the object.
Light is energy, and when it hits an object, its energy can be absorbed by the object, which heats up as a result. In fact, objects can absorb not only visible but also other kinds of invisible light (ultraviolet, infrared, etc.). Absorbed light is invisible and doesn't affect our images.
Direct and Indirect Lighting
When we consider only the first bounce of light, we are only considering direct lighting: light that bounces from an object and straight into the camera. However, light bounces around everywhere (and it bounces even more if we consider that it’s not exactly a particle) and many times.
This is why we also have to include extra light in our scenes that fills the very dark parts of the shadows representing these extra rays of light bouncing everywhere. This extra light is called indirect light, ambient light, or global illumination.
Indirect light is very weak: if a single bounce usually results in 18% of the original light bounced, 2 bounces would result in 3.24% of the original light intensity. Nevertheless, it is very noticeable because a bit of light on a completely dark surface is very noticeable.
Indirect lighting is quite hard to get right because we have to consider the entire scene, how light bounces between objects, how color is being added to each object, etc. Some of the most common approaches include:
- Calculate it accurately tracking how light should bounce around the scene and combine it with the direct lighting. This process is obviously the most accurate, but it is very slow in CGI and very hard to get right in illustration:
- Add a fill/ambient color: instead of leaving the shadowed parts of our scene completely dark, we use a base color that fills them (usually the sky color or the color of the largest light source) to represent how the environment light is filling these dark areas with its bouncing indirect light.
- Use the base color of each object: it's frequently used in illustration. Instead of starting with a black canvas and adding the light from each source, we usually start with base colors and add shading on top of them. This way, shade areas will keep some of the color that indirect lighting would light, allowing us to see the base color of the surfaces.
If we start from a base color and darken it for shadow areas while keeping the base color perceivable, we are recreating indirect light reaching those shadow areas.
Warning: some people also refer to the base color of the object as the albedo color or diffuse color. Technically, diffuse color should include shading (light+shadow) and albedo color should be the flat color (without lights or shadows), but these terms are commonly used without distinction.
- Add a fill light: in CG, we can add a fill light (sometimes it's the same as an ambient color), which is a light that illuminates all objects from all angles.
A similar approach would be to capture the environment as a 360º image and use it as a fill light to fill the shadows with the color of the environment. For instance, we can use a Skylight in Unreal Engine to capture the scene and use it to fill dark areas simulating indirect lighting in real-time.
The Story So Far
So, how can we form an image using what we have discussed so far? Let’s take a look:
Starting from complete darkness, we add light sources to our environment and calculate the direct lighting: light comes out of the light sources, bounces once on the environment, and goes into the camera. As we have seen, there are diffuse and specular bounces:
This is nice, but light in real life bounces more than once – we need to incorporate these extra bounces (indirect light) into our scene:
And aside from bounces, light can also go through objects (transmission):
When we combine everything together, we have our render:
So, what we need to represent light is the sum of direct lighting (diffuse and specular), transmission, and indirect lighting. We could also add some extra effects, such as caustics, bloom, motion blur, etc., but those are the basic pieces that we should keep in mind.
Depending on our media, we approach this in different ways:
- In non-realtime CGI, we throw rays from the light sources into the scene (ray tracing), track how they bounce, and add them together to generate the image.
- In real-time CGI, we generate temporary images of the scene with the information we need (color, roughness, depth, etc.) and use optimized math formulas that calculate the color of each pixel using the scene settings and these temporary images.
- In illustration, we usually start with the diffuse color because it is usually the most important component, add shadows (so we get the direct diffuse reflections and a base for indirect lighting), add specular reflections on top of all, and finally tweak everything until we get the desired result.
Light Has to Get Somewhere
When light hits an object, the incident light is either reflected, transmitted (goes through the object), or absorbed; and it is conserved during this process: incident light is equal to the sum of reflected, transmitted, and absorbed light. In real life, there are other processes that can affect light, but they are negligible for rendering.
Because absorption is invisible, we can reduce the amount of light that is bounced from the object and assume that the rest is absorbed. However, we can’t increase it because we would be generating light from nothing. This is relevant as old lighting models in CGI did not respect this law, and we could have objects reflecting more light than they should.
Reflections in Detail
When light interacts with an opaque object, some part of it gets absorbed by the object (which gets hot as a result), and the rest of it bounces. When that bounced light reaches a camera or our eyes, we can see the object.
The percentage of light that gets reflected by a material is called the Albedo, and it ranges widely between different materials.
If we had a material with an albedo of 100, it would reflect all light. It would not only be a perfect mirror but it would also be very cold as sunlight just wouldn’t heat it directly. Usually, the highest albedo is found on new clear snow at about 80. The main implication of this is that we should avoid using pure white as a color because a surface with 100% pure white would actually have to be actively emitting light, not just reflecting it. Of course, there are other factors to consider (white balance, exposure, eye adaptation) but as a general rule of thumb, it's a good idea to avoid using pure white and pure black.
There are two main types of light reflection: specular and diffuse reflection. The sum of these reflections gives us the albedo.
Non-metallic materials (dielectric) reflect between 2 and 5% (4% being the average) of light in a specular way and a wider range of light: 0.5-75% in a diffuse way (14% on average). The sum of reflected light (specular + diffuse) is the albedo value (18% on average). The rest gets absorbed by the material as heat.
Metals are weird, they reflect 50-99% of light in a specular way and don’t have diffuse reflections.
Diffuse Bounces in Detail
As we have seen, in a diffuse bounce, the ray of light can penetrate slightly the surface of the object interacting with it and releasing back out in a random direction.
Diffuse bounces carry the color of the object.
In a diffuse bounce, light penetrates the outermost layers of the object, the object absorbs part of the light (heating as a result) and releases the light in all directions, which is now colored as it got partially absorbed by the object.
Diffuse bounces throw light in all directions, everywhere.
This means that a specific point of the object will have the same light intensity no matter where we look at it from.
The point of the object that is closest to the light will have the most brightness, and the less exposed points will be dark. This is a very important distinction from the specular bounces, where the viewing angle does matter.
The surface roughness is irrelevant for diffuse bounces.
Since light gets scattered everywhere with diffuse bounces, the surface roughness is irrelevant for diffuse bounces: we can polish a red surface and make its surface smoother, but it will always be red.
Specular Bounces in Detail
In my opinion, specular bounces are easier to understand because it’s what comes to our heads when we think of a bounce.
The light bounces back from the object at a symmetrical angle and goes towards the viewer creating a specular reflection, like a ball thrown towards a wall.
Specular reflections keep the color of light.
Since the light interacts very briefly with the object, specular reflections keep the color of the light source, ignoring the color of the object. This is the white highlight that we see on a smooth plastic surface: it doesn’t matter what the color of the plastic is, this reflection is always the color of the light (usually white) because that’s the color of the light source, and the specular highlight doesn’t modify it.
These objects have different colors (set by the diffuse bounces), but their specular highlight is the color of the light (white).
In a specular reflection, the entire environment is being reflected, but light sources are much brighter than the environment, so a lot of times these light sources are the only specular reflection that we notice. These reflected light sources are usually named specular highlights.
This traffic light projects a colored specular reflection on the ground. The entire environment is being reflected, but we mostly see the light because it is a much stronger light source than the rest of the environment.
Specular reflections are view-dependent.
This kind of reflection is dependent on the viewer's angle: we only see the light that is perpendicular to the surface we are looking at. If we change the viewing angle, the highlight will “move (relative to the object)”. The intensity of the reflection will be greater as the viewing angle gets more parallel to the surface.
The specular reflection on this bird figurine seems to be placed on the eye in the first picture, while in the second image seems to be placed on the spine.
Specular reflections look different depending on surface roughness.
If the surface is perfectly smooth, the reflected light will be very similar to the source (like a mirror), and if it's rough, the bounced image will be blurry. Instead of having to model microscopic details to represent these surfaces, computer shaders usually have a way of simulating those details, usually a roughness or smoothness value that we can adjust using a value or a texture.
Notice how all the spheres are always red: the color of the object depends on diffuse reflections, which are independent of surface roughness (no matter how much we polish a red ball, it is still red). Only specular reflections are affected by surface roughness.
The specular highlight of a smooth surface looks brighter than the specular highlight of a rough surface because the rough surface scatters light everywhere, while the smooth surface directs it towards the viewer. The amount of reflected light is the same, the rough surface simply scatters it, making the highlight larger and dimmer.
Now, let’s imagine that we have a rock and a pool full of water. Let’s throw the rock directly into the water, simply letting it fall down from a great height. Will it bounce?
Of course not. It simply goes through the water and falls to the sea floor. But what if we throw it at an angle? At a 45º angle, the rock will probably still fall down, but at very low angles, the rock bounces (skipping stones). At some angles, where the movement direction of the rock is almost horizontal; it's more likely for the rock to bounce than it is to go through the surface.
The same thing happens with light when it comes to specular bounces.
If we throw a ray of light perpendicular to a surface, it is more likely to be absorbed by the surface than it is to bounce. However, if we throw it almost parallel to the surface, it will be more likely to bounce and generate a specular bounce.
This effect is called the Fresnel effect, and it basically means that surfaces are more specular when looked at at extreme angles. Because of this, specularity is calculated at a perpendicular viewing angle, called f0; instead of any angle.
One of the clearest examples of this is water: when we look at a water surface straight down, it is transparent and we can see what's inside the water; and when we look at it horizontally (looking at the sea at the horizon), the specular bounces are much more likely, and the water reflects light like a mirror.
In this image, we can see through the water when looking at the nearby rocks, but the far away zones look more reflective because water has a fresnel effect: it is much more specular when looked at from a parallel angle and less specular when seen from a perpendicular angle.
Metallic objects are weird. Metals are very, very dense. So dense that it’s pretty much impossible for a metal in the real world to become transparent (gold leaves can be a hundred atoms wide and still be opaque).
When light hits a metal surface, most of it bounces off: while most materials have a lot of diffuse reflections and a few specular reflections, metals have a lot of specular reflections and no diffuse reflections. Light simply cannot get inside the metal surface to interact with the metal atoms, get partially absorbed and get out in a diffuse bounce. Instead, it just bounces off. In a metallic object, around 50-99.8% of the light gets reflected specularly, and the rest gets absorbed.
What color is a mirror? It's hard to tell because mirrors are made of metals and they reflect most of the light in a specular way.
Some metals can also add a little bit of color to the reflected light making it look like they have a color (gold, copper, etc.), but in reality they are just modifying the color of reflected light: specular highlights keep the color of the light in non-metallic surfaces, but can be altered in metallic surfaces.
In the case of metallic surfaces, since most of its surface is reflecting the environment, their look can vary immensely depending on the environment and the viewing angle. As a result, they are hard to draw, and if we wanted to render them correctly in 3D, we would have to “render again” the entire scene. A common solution is to make these metal parts very rough in order to make the reflection quite blurry and avoid distinguishable details that might not fit with every environment.
When a light ray reaches an object, it can go through it. This process has many names. I've decided to use the term transmission, which is the one used in ray tracing CGI.
Keep in mind that light has to be conserved: if a transparent object has reflections or if it's colored, light has to be dimmer when it goes through it. For instance, when a surface gets wet, it might have a stronger specular reflection because of the water on top of it. The light that is getting reflected specularly doesn’t reach the object and doesn’t contribute to the diffuse reflections making the object look darker.
Transmission can take many forms.
When light passes through many different mediums with different properties, it appears to bend. This is what happens in real life with water, glass, etc.
Light can travel at different speeds depending on the medium it’s passing through. You might remember that the speed of light is about 299 792 458 m/s, but that is measured in a vacuum. While it is going through a medium it might go slower (not 100% true, but let's skip the relativity theory) depending on the refraction index of that medium.
In some mediums, the light goes faster or slower than in the air, and that can cause incident light rays to bend when going through the medium in a phenomenon called refraction.
Heavily compressed air is denser than regular air, and the light goes through it slower. This is why explosions can create visual shockwaves: air is much denser here and we get refraction effects between regular air and heavily compressed air.
A completely translucent object is invisible, however, it can still be perceived because it bends light, changing how objects behind it are seen.
Refraction can also cause other related effects, such as rainbows, prisms, iridescence, etc.
The ray of light goes through the object and its direction is unchanged. This is what happens in real life with most gasses. Visually, a completely transparent object is invisible. However, a partially transparent object can be seen.
A partially transparent object will tint the objects behind it with its diffuse color. This type of transmission is mostly used as a cheap way of translucency in CGI: in real life, almost all objects have a refraction index distinct from 1 (air) and will bend light in some way.
Subsurface scattering is a mix between diffuse reflection and translucency: light can penetrate an object, start reflecting inside the object with diffuse bounces, and get out the other side of the object, especially on thin surfaces where it is more likely for light to go through the object.
Subsurface scattering is colored, with a color that is a mix between the diffuse color of the object (because of the light rays diffusely scattered) and the color of the light (because of the light rays transmitted through the object). It can make surfaces look emissive when looked at from the shadowed side, and it is sometimes faked with emissive materials.
Combining Light Sources
What if we have different light sources? How do they add up?
If we take a photograph with 4 different light sources turned on and 4 photographs (or renders) with each individual light turned on and the rest off, can we simply add the individual photographs to generate the same result?
4 light sources turned on
Each light source turned on individually
If we compare the generated image with the one with all lights turned on, we can see that they are basically the same. This means that we can work on each light source separately and add them; light sources can be added linearly.
Well, kind of. While the light from different light sources can be added, keep in mind that our eyes adjust to the amount of light that we are seeing, and past a certain threshold, our eyes readapt in a similar way to how we stop perceiving a strong smell after a while so that we can focus on other smells (also, gamma correction and other effects could interfere).
This is yet another reason why you should avoid 100% white: our eyes would adapt to avoid losing the information that we can’t see because our light receptors are flooded.
In CGI, we usually start with black color for the entire scene and start adding lights. However, when drawing we usually start with the diffuse color and add both lights and shadows.
A shadow is the absence of light. Depending on their appearance, shadows can be split into three groups:
- Form shadows – shadows created on the surface of objects simply because they are less exposed to the light. Form shadows come from the lack of diffuse reflections: the parts of the object that are exposed to the light will reflect it, but the parts that are less exposed (facing away from the light) will not, and they will look darker. These shadows are usually smooth and subtle and give us a lot of information about the volume of the object.
- Cast shadows – shadows created when an object or a part of an object gets between a source of light and another object. Unlike form shadows, which affect only the same object, cast shadows can affect nearby objects, occluding them from the light source. These shadows are usually harder and less subtle than form shadows, and they give us information about the location of the objects in our scene.
- Ambient Occlusion: when an object gets close to another, light is less likely to reach the space in between objects, and that space looks darker. We can fake this effect by darkening these zones, usually in real-time environments as a cheap way of mimicking light bouncing around the scene, which is a very expensive effect. In reality, Ambient Occlusion is a mix of cast and form shadows, but we separate it in order to have more creative control over our scenes.
Much like multiple light sources can be combined together, shadows from multiple light sources can overlap and become darker.
However, a single source of light cannot generate overlapping shadows (a mistake we sometimes make when drawing light). Each light source generates its own set of shadows. A form shadow and a cast shadow formed by the same light wouldn’t overlap, they would combine.
Shadows are not always dark.
Light bounces everywhere (thanks to indirect lighting). Some of this light will likely reach shadowed areas and bounce back to the viewer allowing us to see the color of areas in shade.
The brightness of shadowed areas will depend on how much indirect light we have in our scene: in the desert, there is only one light source and no buildings, trees, or other objects that might bounce light and fill those shadows with color: we have very little indirect lighting (we will always have some), and shadows look dark and have very little color.
The shadow of this girl is very dark because there is only one light source (sun) and no surfaces where sunlight can bounce to fill it.
On the other hand, during an overcast (cloudy) day, clouds bounce light everywhere, shadows get filled with the bouncing light, and we can even get to a point where shadows disappear.
This woman has almost no shadow: the buildings, clouds, and rain are reflecting light everywhere.
When we have separate light sources casting shadows, these shadows can overlap. In real life, we mostly have one light source (the sun), so having several overlapping shadows from several light sources looks unnatural, and we usually try to avoid them or we try to soften those shadows.
These shadows overlap because we have multiple light sources, which looks unnatural.
In order to avoid this effect, lighting experts use larger sources of light that form softer shadows (such as windows or large lights) or use deflectors that scatter light in all directions.
Shadows can have smooth or hard edges.
Cast shadows can have different degrees of border smoothness. I used to think that this depends on the distance between the shadow and the shadow-casting object, but I was slightly off.
In the case of directional light, such as the sun, all light rays are parallel (the sun is so far away from the Earth that when light rays reach us they are almost parallel). This generates hard shadows:
However, when we have a light source that is closer to the object, shadows appear smoother.
Once we get closer to the object, light rays approach the object at different angles, smoothing out the shadows. The furthest away from the light source, the smoother these shadows will get because light rays at the edges have traveled a longer distance and since they are traveling at slightly different angles, they separate more.
For reference, the light rays from the sun are almost completely parallel but they do have a small variance of 1-1,5º so we should be able to see soft shadows from direct sunlight, especially at long distances from the shadow casting object. Increasing the size of the light source also softens shadows.
You might think that if sunlight rays are mostly parallel, a window would let light enter a room also as parallel rays. However, we also have to consider indirect light going through the window from all directions, as well as diffraction.
So, in this tutorial, we took a look at the main light effects that we should keep in mind when rendering a scene: emission, direct and indirect light bounces (both specular and diffuse), transmission, and absorption.
We also took a look at some related effects, such as metallic objects, refraction, and combining several light sources and shadows.
Now that we have in mind the different parts that we need to render a scene, I would like to take a closer look at how we approach these different parts from a non-real-time approach (using ray tracing), a real-time approach (using rasterization), and an illustration approach (taking a look at the main shading techniques used in illustration).
This tutorial took me much longer than I thought, but I also learned a lot more than expected while researching it. I'm not sure how much time I'll need to finish each part, so wish me luck!
Thank you for your time, and I hope it was useful. If you want to learn more about lighting, I strongly recommend taking a look at Light for Visual Artists by Richard Yot.
Carlos Lemos, 3D Artist
You may find these articles interesting