How feSpecularLighting Creates 3D SVG Highlights

The feSpecularLighting SVG filter primitive simulates realistic 3D surface highlights by calculating specular reflection across a 2D graphic using the Phong reflection model. By treating the alpha channel or luminance of an input image as a heightmap, the filter calculates surface normals and simulates how a virtual light source reflects directly into the viewer’s eye, adding depth, gloss, and metallic or plastic textures to otherwise flat vector artwork.

The Virtual Surface Heightmap

To create a three-dimensional effect from a two-dimensional object, feSpecularLighting generates an elevation map (bump map) based on the opacity of the input element (in="SourceAlpha" or in="SourceGraphic").

Light Source Computation

The specular calculation requires a directional light vector (\(\vec{L}\)). In SVG, this is defined by nesting one of three light source elements inside feSpecularLighting:

The Phong Reflection Model

feSpecularLighting calculates light intensity using the Phong reflection model, which isolates the sharp, mirror-like reflections (specular highlights) that occur when light bounces off a glossy surface toward the viewer’s eye vector (\(\vec{V}\)).

The brightness at any given pixel is determined by: \[I = k_s \cdot (\vec{N} \cdot \vec{H})^{\text{specularExponent}} \cdot \text{LightColor}\]

Where: * \(\vec{H}\) (Halfway Vector): The vector halfway between the light direction and the viewer direction. * specularConstant (\(k_s\)): Controls the reflection coefficient. Values greater than 1.0 boost highlight brightness, producing metallic finishes. * specularExponent: Controls surface shininess or smoothness. Lower values (e.g., 5 to 10) spread the highlight across a wide, soft area, simulating matte or dull materials. Higher values (e.g., 50 to 100+) narrow the highlight into a tight, sharp glint, simulating polished glass or wet surfaces. * lighting-color: Defines the RGB color of the reflected highlight.

Compositing the Result

The raw output of feSpecularLighting is not the lit graphic itself, but an isolated light map containing only the calculated highlights against a transparent or black background.

To complete the 3D simulation, the highlight layer must be combined with the underlying artwork using <feComposite> or <feMerge>. Typically, developers use <feComposite operator="in"> to restrict the highlight to the element’s boundaries and <feComposite operator="arithmetic"> to add the specular highlights directly over the original color layer and any ambient/diffuse lighting generated by <feDiffuseLighting>.