A Look at SVG Light Source Filters

The following is a guest post by Joni Trythall. Joni recently finished a Pocket Guide to Writing SVG. I've been excited about SVG for a while now, working with it, learning about it, writing about it... but there is so much to know. It really is another whole universe of the web. So I reached out to Joni to see if she would like to write something for CSS-Tricks on SVG and she agreed! Here's Joni on lighting in SVG, something I know I knew nothing about before reading this.

SVG has its own set of filter effects that, when writing SVG, allow the author to combine several of these effects and apply the filter to the graphic.

Some of the more fantastic features of SVG filtering revolve around the light source. You can apply a lighting effect to SVG and then control the details of that through one of three filter effects: fePointLight, feDistantLight, and feSpotLight.

These light source filters allow for some especially neat capabilities. Check out this shiny, lighted apple (as compared to a non-lighted one):

See the Pen 7d39edca68f2d2b2dfe0e7f3728a276a by Joni Trythall (@jonitrythall) on CodePen.

In this post we will review the basic syntax for SVG filters, dive into some of the more common attributes, look at lighting source effect options, and then bring everything together with an SMIL animation experiment.

filter Element

SVG filter details reside within a <filter> element. A <filter> is comprised of several different effects and these effects are then all applied to a graphics element (such as a rectangle, <rect>) or container element (such as a group, <g>).

<svg>
  <defs>
    <filter id="apples">
      < (filter effect) />
      < (filter effect) />
    </filter>
  </defs>
  <rect filter="url(#apples)" />
</svg>

Select Attributes

While there are a great number of filter related attributes, we will specifically be focusing on the ones used here throughout the apple demos.

The following attributes, with the exception of in, are able to be used within any SVG filter effect.

x, y

The x and y attributes within filters set the minimum coordinates on the appropriate axis for the region in which the filter will take place.

result

The result attribute assigns a name to a specific filter effect. This effect can then be referenced by another effect to follow through the in attribute. Both effects must reside within the same <filter> and it allows us to combine several filter effects into one to be applied to a graphic.

A result value is not required, but is useful when looking to reuse specific effects. While its purpose closely resembles that of an id, result values are only useful within the same <filter> element and are therefore not accessible anywhere else in the document.

in

The in attribute specifies the input for a specific filter effect. There are seven value options here, including the name of the result which we just reviewed in the previous section, but perhaps the most frequently referenced are SourceGraphic and SourceAlpha.

If the in attribute is left unspecified and the filter effect is the first listed within the <filter> then it will default to SourceGraphic. Alternatively, if this attribute is left unspecified and is not the first effect listed, then the default will inherit the value of the effect before it.

  • A SourceGraphic value within in sets the input for the filter as the RGB colors of the graphical element to which it is being applied.
  • The SourceAlpha has the same impact as SourceGraphic except black color values are used for the RGB channels input.

Here is a look at the impact these two values have when applying a blurred filter to two identical circles, both having a fill value of #ED6E46:

Lighting Source Filters

Now that we have a familiarity with some of the more common attributes used within SVG filters lets focus on the lighting source effects.

SVG lighting is accessed through the use of feDiffuseLighting or feSpecularLighting filters, which establish its calcluations based on the appropriate component of the Phong lighting model (PDF).

While diffuse light is light that hits a surface and gets scattered equally in all directions, specular light refers to a bright spot of light that gets reflected in a particular direction. The demos throughout this post will only focus on lighting effects accessed through specular light, or feSpecularLighting, or "light that makes all the things look shiny!".

Attributes used within this filter effect, such as specularConstant and specularExponent, set the details of the light based on Phong lighting model calculations.

The basic light filter related syntax going forward will look like this:

<filter>
  <feSpecularLighting>
    < (light source effect) />
    < (light source effect) />
  </feSpecularLighting>
</filter>

Let's take a look at the fePointLight, feDistantLight, and feSpotLight effects that will reside within this specified calculation.

fePointLight

fePointLight establishes a specific point as the main light source when applying the feSpecularLighting filter and is how the shiny apple was achieved in the very first demo.

The appearance of the light not going to the very edge of the apple is created by the value of the feGaussianBlur effect, and a higher value here would create greater blending.

x, y, z

The x, y, and z attributes here determine the location of the light source in the coordinate system on the appropriate axis. z will adjust the perceived size of the point of light by determining its location from the point to the user; a higher value here results in a larger point of light that is "closer" to the user.

feDistantLight

feDistantLight defines a distant light source.

  • The azimuth attribute within feDistantLight defines the clockwise direction angle in degrees for the light source on the XY plane.
  • The value within `elevation` defines the direction angle in degrees of the light source from the XY plane towards the z axis.

The filter on the apple below has an azimuth value of 25px and an elevation value of 40px:

See the Pen 9be1624ee991e2978a922ac39b8bb029 by Joni Trythall (@jonitrythall) on CodePen.

feSpotLight

feSpotLight defines a spot light as a light source.

  • The x, y, and z values establish the location of the light source along the appropriate axis within the coordinate system.
  • The limitingConeAngle restricts the area to which light is projected by disallowing light to render outside of it. This value sets the angle in degrees between the spot light axis and cone. A higher value here results in a less restricted area.

The feSpotLight filter below contains the following specifications: x="400" y="400" z="900" limitingConeAngle="9":

See the Pen 195ed2b4fa8f17b0f8145b9384116a44 by Joni Trythall (@jonitrythall) on CodePen.

Animating Light Sources

Light sources can also be animated. The code for this graphic is fairly complex and lengthy when used inline, but for the sake of science we are going to have the sun moving from one side of the apple tree to the other acting as a "light source".

See the Pen Apple Tree Lighting Animation by Joni Trythall (@jonitrythall) on CodePen.

The sun, aka our pretend light source, is moving across the screen through SMIL animations. In turn, the light source filter on the tree is also being animated in response to the sun's positioning.

An <animate> element must reside within each element to be animated, which are both noted in the HTML.

Conclusion

SVG light source filters can really bring a graphic to life on the screen, testing the boundaries of the two-dimensional limitations of the language. These advanced features allow us to create more complex and detailed images that live within the DOM and can easily become interactive or scripted.

The lighting details addressed here really only scratch the surface concerning the capabilities of SVG filters, but hopefully what we have reviewed inspires you to tinker with it and explore its full potential.

In this post we reviewed some basic <filter> syntax, took a look at a few attributes, focused on some neat lighting sources effects, and then animated these effects in the name of science.


Editor's note: Make sure to check out Joni's Pocket Guide to Writing SVG.