While current trend in web design favors a flat look, I have no doubt that depth will return and we’ll once again see 3-dimensional design elements. When that time comes, SVG will have us covered with a handful of filter primitives that work together to create different lighting effects and bring back the missing dimension into and out of the screen.
The last couple of weeks, I’ve been looking at svg filter primitives that help us modify colors in images and graphics. I first covered the feColorMatrix primitive and followed by covering the feComponentTransfer primitive.
As you might have guessed, I want to talk about filters that help you create lighting effects. There’s a lot to cover. Today I’ll talk about some primitives that define the source of light and the next two weeks I’ll talk about two different types of lighting and the primitive associated with each.
Today’s post will be light on examples. We need to combine what’s here with what I’ll look at next week and the week after. Those posts will offer the examples.
To create lighting effects with SVG you need to specify a few things.
- The type of lighting
- The object to be lit
- The color of the light
- The type of light source
You also need to specify a few things about your choices. For example, when it comes to the light source, where is it located? Where is the light coming from and to what direction is the light pointing?
A lighting filter will take on the following structure.
<type of lighting in="" lighting-color="">
<light source />
</type of lighting>
The two types of lighting are diffuse lighting and specular lighting (I’ll talk more about these next week) and each has an associated primitive. You’ll define the color of the light as an attribute on these primitives and inside the primitive you define the source of light.
I want to talk about all these different parts of lighting effects from the inside out. Let’s start with the different types of light sources. Again, today’s post will be without examples. Consider it preparation for the next two posts.
Light begins with a light source. The sun provides light during the day. At night you probably turn on an overhead light or lamp. If you’re at a concert or watching a play, there’s probably a spotlight shining on the stage.
Each of these different sources lights objects in different ways. The sun effectively lights things equally everywhere. A light bulb does the same, but has a much more limited area over which it works and the intensity of the light quickly fades. A spotlight shines an intense beam, but only over a limited area.
Each of these sources of lights has an associated filter primitive.
- feDistantLight defines a distant light source, similar to how the sun lights everything during the day.
- fePointLight defines a light source that radiates from a single point, similar to how a light bulb lights a room.
- feSpotLight defines a light source similar to a spot light that shines intensely over a small area.
Consider again, the general form of a light filter.
<type of lighting in="" lighting-color="">
<light source />
</type of lighting>
You include one of the three light source primitives as a subelement inside one of the two types of lighting elements. Naturally each of the three primitives takes some additional attributes to define the location of the source.
The feDistantLight Light Source
An feDistantLight source is akin to the sun shinning and lighting up everything. The light shines in a 3-dimensional set of coordinates defined by x, y, and z, but with the feDistantLight source, the z-value is effectively infinite.
To define the location of this light source you need to set two attributes, an azimuth and an elevation.
The azimuth is the direction angle for the light source on the XY plane. You can think of it as the sun’s rays sometimes shining to the east and other times shining to the west. When the azimuth changes, the direction a shadow falls also changes.
The azimuth attribute takes a value in degrees as measured clockwise from the x-axis. The default is 0.
The elevation is the direction angle for the light source from the XY plane towards the z-axis. You can think of it the way the sun casts a longer shadow in the morning and evening as compared to midday. The change in shadow length comes about from a change in the sun’s elevation.
The elevation attribute also takes a value in degrees with the positive z-axis pointing toward the viewer. The default is 0.
Here’s how you might see feDistantLight in your code. Note that you don’t need to specify that the values are in degrees.
<feDistantLight azimuth="15" elevation="45">
Since this might all be a little difficult to picture, here’s an image I grabbed from the spec that illustrates both the azimuth and the elevation.
Hopefully that helps make what’s going on a little clearer.
The fePointLight Light Source
- x = “<number>”—X location for the light source
- y = “<number>”—Y location for the light source
- z = “<<number>"—Z location for the light source
The specific units for x, y, and z will depend on the value set for primitiveUnits on the filter. Also know that the positive numbers along the z-axis mean closer to you, the viewer, and negative numbers mean further away from you and into the background of the screen.
All three attributes have a default of 0, if not set and the further you set an fePointLight source away from the object being lit, the more evenly the object will be illuminated. In theory if the point light source is strong enough and is an infinite distance away, it becomes an feDistantLight source.
Here’s how an fePointLight primitive might look in your code.
<fePointLight x="10" y="50" z="100" />
Hopefully that’s easy enough to understand and remember.
The feSpotLight Light Source
An feSpotLight source is akin to a spotlight shining on an otherwise dark stage. Like a point light, it also has a location, but unlike a point light, it’s light is directed at a specific point and it only lights a limited area.
There are eight attributes for defining an feSpotLight source, the first three are x, y, and z and they work the same as they do for the fePointLight in that they define the location of the light source. Units are again defined by the primitiveUnits attribute on the filter element.
The next three attributes define the location of a point the light is shining on.
- pointsAtX = “<number>”—X location of the point being lit
- pointsAtY = “<number>”—Y location of the point being lit
- pointsAtZ = “<number>”— Z location of the point being lit
As with x, y, and z, the default for all three of these coordinates is 0 and positive z-axis values are toward the viewer. Again these three attributes define the location of what’s being lit as opposed to the location of light source.
The final two attributes, specularExponent and limitingConeAngle define the size of the light beam.
specularExponent is an exponent value that defines how focused the light source is on a single point. The default is 1 and the greater the value, the more focused the beam is on a single point.
limitingConeAngle represents the angle in degrees between the spot light axis and the spot light cone. This probably needs some additional explanation.
If you picture a spot light it produces a mostly linear beam of light that’s somewhat wider at the area it points to than the area where it originates.
The spot light axis is a line running from the center of the light source to the center of the circular area that’s lit. You can similarly draw a line from the point at which the light originates to the perimeter of the same circular area.
The angle between these two lines is the limitingConeAngle. The greater the angle, the wider the area covered by the spot light.
Here’s how an feSpotLight subelement might look in your code.
<feSpotLight x="1-" y="50" z="100" pointsAtX="0" pointsAtY="0" pointsAtZ="0" limitingConeAngle="10" />
You might have noticed that I didn’t include a specularExponent to the previous code. That’s because it gets added as an attribute to the type of light primitive and not the light source subelement. I’ll show you how it works next week.
The color of the light doesn’t need to be white, though that is the default. You can define any color you want using the lighting-color property.
lighting-color = currentColor | <color> \[<icccolor>\] | inherit
You’ll add this property as an attribute of either the feDiffuseLighting or feSpecularLighting filter primitives, which I’ll talk about over the next two weeks.
I hope this post wasn’t too dry. I know it’s example free and some of what I’ve talked about might be a little difficult to picture. It was necessary to talk about the different light sources though, in order to use them in the examples for the types of lighting filter primitives.
Next week I’ll talk a little about the difference between diffuse lighting and specular lighting and then I’ll cover the feDiffuseLighting filter primitive. The week after I’ll talk about feSpecularLighting and I’ll have examples for both that include the light sources I discussed today.
Download a free sample from my book, Design Fundamentals.