Copy Link
Add to Bookmark
Report

Fast Specular Highlights with Local Light Sources and Viewer

DrWatson's profile picture
Published in 
atari
 · 25 Nov 2023

Sebastien Loisel (zed@scylla.math.mcgill.ca)

This described a method for shading triangles in a phong-like way so that we can get specular highlights within triangular faces. In Gouraud shading, if the vertices are all dark, then the entire triangle will be dark, missing any specular highlight that maybe ought to have been in the center of the triangle.

Overview

In screen space, the (x,y,z) difference between the specular reflection vector and the eye vector is linearly interpolated. The norm of this (x,y,z) value itself is enough to let us compute some sort of specular highlight, we only need to look up the value x^2 + y^2 + z^2 in a table to get the actual intensity of the lighting, per pixel. Since x, y and z vary linearly across a scanline, x^2 + y^2 + z^2 varies quadratically and forward differencing can be applied to reduce the number of operations required to 2 adds per pixel plus some set up operations.

Computing the (x,y,z) values in screen space

Let R be the unit vector which points in the direction in which the light is reflected and E be the vector from the vertex under consideration to the eye, normalized.

The specular highlight should be a function of the "difference" between R and E. Traditionally, this difference was measured by the dot product. I suggest that |R-E| may also be an adequate measure.

So R-E is evaluated at each vertex, which yields a "specularity vector" S for each vertex. Note that, if R and E are each of unit norm, the triangle inequality says that |R-E|<=2. Of course, knowing that || is always non-negative, this gives tight bounds as to what values |S|, and therefore |S|2 can take. Since |S|2 is easier to compute than |S| is, |S|2 will be used as an index into a specular color table.

If we want to have some sort of distance attenuation for the specular highlight, we can make this specular color table bi-dimensional, one axis for |S|2 and another axis for distance to light.

Interpolating |S|2 in screen space

We arbitrarily decide to linearly interpolate S across the screen between the vertices for the triangle. This means that, for a given scanline, S varies linearly and that

\mathbf{S}(t) = (at + b, ct + d, et + f)

a, b, c, d, e, f are some scalars and t is the column number (x coordinate) of the current pixel and noting that P(t) = |\mathbf{S}(t)|^2 = \mathbf{S}(t) \cdot \mathbf{S}(t) , we can expand this and find that

P(t) = |\mathbf{S}(t)|^2 = (a^2 + c^2 + e^2)t^2 + (2ab + 2cd + 2ef)t + (b^2 + d^2 + f^2)

Now we wish to evaluate this incrementally and since this is a simple quadratic, we can apply forward differencing:

P(t) = At^2 + Bt + C

with

A = a^2 + c^2 + e^2, \quad B = 2ab + 2cd + 2ef, \quad C = b^2 + d^2 + f^2

then

DP(t) = P(t + 1) - P(t) \\ = A(t^2 + 2t + 1) + B(t + 1) + C - (At^2 + Bt + C) \\ = (2A - B)t + (A + B)

and

DDP(t) = DP(t + 1) - DP(t) = 2A - B

So that, given P(t_0) and DP(t_0) , to evaluate P(t_0+1) we add DP(t_0) to it and to evaluate DP(t_0+1) we add 2A-B to it.

This value can now be used as a look up in the specular highlight table.

A few notes on the specular highlight lookup table

If (and only if) |S|2 > 2 then R and E point away from one another. Perhaps the right thing to do in this case is to add no specular highlight at all.

For |S|2<2, one could use a formula similar to the Phong illumination model to compute the specular highlight table. For instance, one can use:

\large k \cdot \left(1 - \frac{|S|^2}{2}\right)^p (*)

where k would be a "specular coefficient" and p would be a "specular power".

The higher the p, the sharper the specular highlight. The larger the k, the more intense the specular highlight.

Noting the identity

|R - E|^2 = (R - E) \cdot (R - E) = R \cdot R - 2 \cdot R \cdot E + E \cdot E = |R|^2 + |E|^2 - 2 \cdot R \cdot E \\ |R - E|^2 = 2 - 2 \cdot R \cdot E \\ R \cdot E = 1 - \frac{|R + E|^2}{2} = 1 - \frac{|S|^2}{2}

this says that (*) is exactly the Phong specular illumination component, k \cdot (R \cdot E)^p .

Distance Attenuation

In addition, the Phong lighting model often makes use of a light attenuation component, dividing by a factor of A \cdot d^2 + B \cdot d + C where d is the distance between light and point lit.

This value d can be evaluated at vertices and linearly interpolated across the surface. Then, a 2d specular highlight is used instead of the 1d table described above. The entries in the table would be given by something of the form, eg,

\frac{k \cdot (1 - \frac{|S|^2}{2})^p}{A \cdot d^2 + B \cdot d + C}

This is exactly the Phong specular term with distance attenuation.

Note that linearly interpolating from the vertices does not generally yield an exact value for d. (Eg, if we're measuring distance from (0,0) to line segment (1,0)-(1,1), then the distance at the vertices is 1 and \sqrt{(2)} respectively, yielding a linearly interpolated value of \frac{(1+\sqrt{(2)})}{2} for the midpoint while the actual distance is \sqrt {(1.25)} , not the same.)

Multiple Light Sources

Several light sources can be thus rendered, either by having multiple S and d values to interpolate per surface, or using a multipass algorithm and an accumulation buffer.

Diffuse and Ambient components

Diffuse and ambient components should be obtained by another method and accumulated with the specular value.

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT