ShiniesThe diffuse lighting model works reasonably well for a smooth, matte surface. Few objects
in reality conform to this archetype. Therefore, in order to more accurately model real
objects, we need to improve upon this. Let us focus on making objects appear shiny.Shiny materials tend to reflect light more strongly in the opposite direction from the
angle of incidence (the angle between the surface normal and the incoming light direction).
This kind of reflection is called a specular reflection. A perfect
specular reflector would be a mirror.One way to show that an object is shiny is to model specular
highlights. A specular highlight is a bright highlight on an object caused
by direct illumination from a light source. The position of the highlight changes with the
view direction as well as the light direction.Modelling true specular reflection would require reflecting all light from objects in the
scene, whether direct or indirect. However for many objects, like shiny plastics and the
like, indirect specular reflections are very weak. Thus, by modeling direct specular
reflections, we can make an object appear shiny without having to do too much work.We will look at several models for specular highlights and reflection. The Lambertian
diffuse reflectance model was reasonably good for modelling diffuse lighting, but there are
several models for specular reflection that should be considered. They vary in quality and
performance.Note that these models do not throw away diffuse lighting. They all act as supplements,
adding their contribution into the overall result for the lighting equation.MicrofacetsAll of these specular reflection models work based on an assumption about the
characteristics of the surface. If a surface was perfectly smooth, then the specular
highlight from a point light would be infinitely small (since point lights themselves
are infinitely small).Notice that the intensity of the reflected light depends not only on the angle of
incidence but also on the direction to the viewer. This is called the angle
of view or viewing angle. Viewing position A
detects the light specularly reflected from the surface at the point P, but the viewing
position B does not.Surfaces however are rarely perfect specular reflectors (mirrors are the most common
perfect reflectors). Surfaces that seem smooth from far away can be rough on closer
examination. This is true at the microscopic level as well, even for surfaces that
appear quite smooth. This roughness can be modelled by assuming that a surface is
composed of a number of microfacets.A microfacet is a flat plane that is oriented in a single direction. Each microfacet
reflects light perfectly in that direction. Surfaces with microfacets would look like
this:It is part of the microfacet model's assumption that many microfacets on a surface
will contribute to the light returned under a single pixel of the final image. So each
pixel in the rendered image is the result of an aggregate of the microfacets that lie
under the area of that pixel on the surface.The average normal of the microfacets is the surface normal at that point. The
relative smoothness of a surface can therefore be modeled as a statistical distribution
of the orientation of microfacets on the surface. A smooth surface has a distribution
close to the average, while a rough surface has a broader distribution.Thus, a model of specular reflections includes a term that defines the overall
smoothness of the source. This is a surface characteristic, representing the
distribution of microfacets using whatever statistical distribution the particular
specular model is using. One of the main differences between specular models is the kind
of statistical distribution that they use.Specular highlights are formed because, even though the surface normal may not be
oriented to directly reflect light from the light source to the viewer, some microfacets
may still be oriented to reflect a portion of that light. A microfacet distribution
model determines the proportion of microfacets that happen to be oriented to reflect
light towards the viewer.Smooth surfaces, those who's microfacets do not deviate much from the surface normal,
will have a small, bright highlight. Rough surfaces, who's microfacets are oriented in
wildly divergent directions, will have a much dimmer, but larger specular highlight.
These highlights will have positions and shapes based on the angle of incidence and the
angle of view.Note that specular reflectance models do not become diffuse reflectance models when
taken to the extreme case of maximum roughness. Specular reflection represents a
different mode of light/surface interaction from diffuse reflection.Phong ModelThe simplest model of specular illumination is the Phong model.
The distribution of microfacets is not determined by a real statistical distribution.
Instead it is determined by... making things up.On Phong and NomenclatureThe term Phong shading was once commonly used to refer to what we
now know as per-fragment (or per-pixel) lighting. That is, evaluating the lighting
equation at every fragment over a surface. This term should not be confused with the
Phong specular lighting model. Because of this, the term Phong
shading has fallen out of common usage.The Phong model is not really based on anything real. It does not deal in microfacet
distributions at all. What the Phong model is is something that looks decent enough and
is cheap to compute. It approximates a statistical distribution of microfacets, but it
is not really based on anything real.The Phong model states that the light reflected in the direction of the viewer varies
based on the angle between difference between the view direction and the direction of
perfect reflection. Mathematically, the Phong model looks like this:Phong Specular TermThe Phong term is multiplied by the light intensity in the lighting equation.The brightness of the specular highlight for a particular viewing direction is based
on raising the cosine of the angle between the view direction and the reflection
direction to a power. As previously stated, this model is not based on anything real. It
simply creates a bright somewhat-circular area on the surface. This area gets dimmer as
the viewer is farther from the direction of perfect reflection.The s term in the equation represents the roughness of the surface.
A smooth surface, which should have a smaller highlight, has a large
s. Since the cosine of the angle is a number on [0, 1], taking it
to a power greater than 1.0 will make the number smaller. Therefore, a large
s exponent will make for a small highlight.The specular exponent can range from (0, ∞). A small exponent makes for a rougher
appearance, while a large exponent suggests a shiny surface.Specular AbsorptionThe Phong term computed above is then multiplied with the light intensity. This
represents the maximum light reflected along the view direction.However, just as with diffuse lighting, surfaces can absorb some quantity of the
light that would be specularly reflected. We could use the diffuse color here,
multiplying it by the specular term. But this would not be physically correct for
many kinds of objects.Many surfaces, particularly certain man-made pigments and plastics, have multiple
layers to them. The top layer will specularly reflect some portion of the light.
However, it will also let some portion of that light reach lower layers. These
layers have stronger diffuse reflectance. So the specular absorption on the surface
has different characteristics than the diffuse absorption in the lower layers.
Usually, the specular layer reflects equally on all wavelenths, so the specular
highlight tends to be the color of the light itself.Notably, metals do not do this. Their diffuse absorption tends to be the same as
their specular absorption. So while blue plastic under white light has a white
specular highlight, gold metal under white light has a gold highlight.Drawing PhongThe Phong Lighting tutorial demonstrates the
Phong specular model.The tutorial is controlled similarly to previous lighting tutorials. Clicking and
dragging with the right mouse button controls the orientation of the cylinder.
Pressing the T key will swap between the scaled and unscaled
cylinder. The Y key toggles the drawing of the light source. The
B key will toggle the light's rotation on/off. Pressing the
Space Bar toggles between drawing the uncolored cylinder and
the colored one.The light's position is mostly controlled as before, with the
I,J, K, and
L keys. The specular value is controlled by the
U and O keys. They raise and low the specular
exponent. Using Shift in combination with them will raise/lower the
exponent by smaller amounts.The G key toggles between a diffuse color of (1, 1, 1) and a
darker diffuse color of (0.2, 0.2, 0.2). This is useful for seeing what the specular
would look like on a darker surface color.The H key selects between specular and diffuse, just specular and
just diffuse. The ambient term is always used. Pressing ShiftH will toggle between diffuse only and diffuse+specular.The rendering code is nothing you have not seen in earlier tutorials. It loads 6
programs, and uses the various controls to select which to use to render.There are two vertex shaders in use. One that takes the position and normal
attributes, and one that takes them plus a per-vertex color. Both of them output the
camera-space vertex normal (computed with a normal matrix), the camera-space vertex
position, and the diffuse color. In the case of the shader that does not take a
per-vertex color, the diffuse color output is taken from a uniform set by the
code.The fragment shaders are more interesting. They do lighting in camera space, so
there is no need for the reverse-transform trick we used previously. The shaders
also use light attenuation, but it only varies with the inverse of the distance,
rather than the inverse squared.The main portion of the specular+diffuse fragment shader is as follows:Phong Lighting Shadervec3 lightDir = vec3(0.0);
float atten = CalcAttenuation(cameraSpacePosition, lightDir);
vec4 attenIntensity = atten * lightIntensity;
vec3 surfaceNormal = normalize(vertexNormal);
float cosAngIncidence = dot(surfaceNormal, lightDir);
cosAngIncidence = clamp(cosAngIncidence, 0, 1);
vec3 viewDirection = normalize(-cameraSpacePosition);
vec3 reflectDir = reflect(-lightDir, surfaceNormal);
float phongTerm = dot(viewDirection, reflectDir);
phongTerm = clamp(phongTerm, 0, 1);
phongTerm = cosAngIncidence != 0.0 ? phongTerm : 0.0;
phongTerm = pow(phongTerm, shininessFactor);
outputColor = (diffuseColor * attenIntensity * cosAngIncidence) +
(specularColor * attenIntensity * phongTerm) +
(diffuseColor * ambientIntensity);The initial section of code should be familiar. The Phong specular computations
start with computing the direction to the camera. Since we are working in camera
space, we know that the camera is at the origin (0, 0, 0). The direction from point
A to point B is the normalization of B - A. Since the destination point is at the
origin, that becomes simply -A, normalized.The next line computes the direction of perfect reflection, given the light
direction and the surface normal. The function here, reflect,
is a standard GLSL function used for precisely this purpose. Notice that the
function in question requires the that the light direction is the direction
from the light. Our light direction is the direction to the
light. This is why it is negated.This function is useful, but it is important to know how to compute the reflection
direction on your own. Here is the formula:Vector ReflectionThe L vector is the direction to the light, so negating it produces the vector
from the light.From here, the Phong term is computed by taking the dot product of the reflection
direction and the view direction, clamping it to 0, 1. The next line, where we use
the angle of incidence, is very important. What this line does is prevent us from
having a specular term when the surface normal is oriented away from the light. If
this line were not here, it would be possible to have specular highlights appear to
shine through a surface. Which is not particularly
realistic.The GLSL standard function pow is next used to raise the
Phong term to the power. This function seems generally useful, but it has a large
number of limitations. The pow function computes XY, where X is the first parameter and Y is the second.This function only works for values of X that are greater than or equal to 0; it
returns undefined values (ie: anything) otherwise. Clamping the Phong term ensures
this. Also, if X is exactly 0.0, then Y must be strictly greater than zero;
undefined values are returned otherwise. These limitations exist to make computing
the power function much faster.And for Phong specular computations, the limitations almost never come into play.
The cosine of the angle is clamped, and the specular exponent is not allowed to be
zero.Notice that the specular term is added into the diffuse and ambient terms. This
has meaning for the intensity issue we have seen before. If the diffuse and specular
colors are too large, and the light attenuation is quite small, then the resulting
values from the lighting equations can be larger than 1.0 in magnitude. Since OpenGL
automatically clamps the colors to 1.0, this can cause unpleasant effects, where
there appears to be a very bright, white area on a surface.Visual SpecularHaving even a weak specular term can make a significant, if subtle, difference. In
our case, the specular color of the material is a fairly weak (0.25, 0.25, 0.25).
But even with a rough specular highlight, the surface looks more physically
reasonable.In particular, it is interesting to note what happens when you use a very dark
diffuse color. You can activate this by pressing the G key.If there was no specular term at all, you would see very little.. The specular
highlight, even with the fairly weak specular reflection of 0.25, is strong enough
to give some definition to the object when seen from various angles. This more
accurately shows what a black plastic object might look like.One thing you may notice is that, if you bring the light close to the surface, the
specular area tends to have very sharp edges.This is part of the nature of specular reflections. If the light is almost
perpendicular to the surface, the specular reflection will shine brightest when the
light is almost eclipsed by the surface. This creates a strong discontinuity at the
point where the light is no longer in view.You generally see this most with rough surfaces (small exponents). With smoother
surfaces, this is rarely seen. But this is not the only visual oddity with Phong and
having small exponents.If you drop the exponent down to the minimum value the code will allow, you will
see something like this:This ring area shows one of the main limitations of the Phong model. When trying
to depict a surface that is rough but still has specular highlights, the Phong model
starts to break down. It will not allow any specular contribution from areas outside
of a certain region.This region comes from the angle between the reflection direction and the view
direction. This area is the region where the reflection direction and view direction
are more than 90 degrees apart.Under the microfacet model, there is still some chance that some microfacets are
oriented towards the camera, even if reflection direction is pointed sharply away.
Thus, there should be at least some specular contribution from those areas. The
Phong model cannot allow this, due to how it is computed.What all this tells us is that Phong works best with larger exponents. Small
exponents show its problems and limitations.Blinn-Phong ModelThe problem with Phong, with regard to the reflection and view directions being
greater than 90 degrees, can be solved by changing the computation. This modified model
is called the Blinn-Phong specular model or just the
Blinn specular model.It is no more physically correct than the Phong model. But it does tend to account for
more than Phong.The main problem with Phong is that the angle between the view direction and the
reflection direction has to be less than 90 degrees in order for the specular term to be
non-zero.The angle between V and R is greater than 90 degrees. Cases like this are not modeled
correctly by Phong. There could be microfacets at the point which are oriented towards
the camera, but Phong cannot properly model this. The problem is that the dot product
between the view direction and reflection direction can be negative, which does not lead
to a reasonable result when passed through the rest of the equation.The Blinn model uses a different set of vectors for its computations, one that are
less than 90 degrees in all valid cases. The Blinn model requires computing the
half-angle vector. The half-angle vector is the direction
halfway between the view direction and the light position.Half-Angle VectorWhen the view direction is perfectly aligned with the reflected direction, the
half-angle vector is perfectly aligned with the surface normal. Or to put it another
way, the half-angle is the direction the surface normal would need to be facing in order
for the viewer to see a specular reflection from the light source.So instead of comparing the reflection vector to the view direction, the Blinn model
compares the half-angle vector to the surface normal. It then raises this value to a
power representing the shininess of the surface.Blinn Specular TermThe angle between the half-angle vector and the normal is always less than 90 degrees.
So the Blinn specular model produces similar results to the Phong model, but without
some of Phong's problems. This is demonstrated in the Blinn vs
Phong Lighting tutorial.The controls are similar to the last tutorial. Pressing the H key
will switch between Blinn and Phong specular. Pressing ShiftH will switch between diffuse+specular and specular only. Because the specular
exponents have different meanings between the two lighting models, each model has a
separate exponent. The keys for changing the exponent values will only change the value
for the lighting model currently being viewed.The real work here is, as before, in the shader computations. Here is the main code
for computing the diffuse + Blinn illumination.Blinn-Phong Lighting Shadervec3 lightDir = vec3(0.0);
float atten = CalcAttenuation(cameraSpacePosition, lightDir);
vec4 attenIntensity = atten * lightIntensity;
vec3 surfaceNormal = normalize(vertexNormal);
float cosAngIncidence = dot(surfaceNormal, lightDir);
cosAngIncidence = clamp(cosAngIncidence, 0, 1);
vec3 viewDirection = normalize(-cameraSpacePosition);
vec3 halfAngle = normalize(lightDir + viewDirection);
float blinnTerm = dot(surfaceNormal, halfAngle);
blinnTerm = clamp(blinnTerm, 0, 1);
blinnTerm = cosAngIncidence != 0.0 ? blinnTerm : 0.0;
blinnTerm = pow(blinnTerm, shininessFactor);
outputColor = (diffuseColor * attenIntensity * cosAngIncidence) +
(specularColor * attenIntensity * blinnTerm) +
(diffuseColor * ambientIntensity);The half-angle vector is computed by normalizing the sum of the light direction and
view direction vectors. As before, we take the dot product between that and the surface
normal, clamp, then raise the result to a power.Blinn specular solves the Phong problem with the reflection direction.The Blinn version is on the left, with the Phong version on the right.The Blinn specular exponent does not mean quite the same thing as the Phong exponent.
In general, to produce a highlight the same size as a Phong one, you will need a larger
Blinn exponent. Play around with the different exponents, to get a feel for what Blinn
and Phong can and cannot achieve.Hard Specular EdgeThere are still a few artifacts in the rendering. For example, if you arrange the
light, object, and camera as follows, you can see this:The cylinder looks like it has a very sharp corner. What causes this? It is caused
by this line in the shader:blinnTerm = cosAngIncidence != 0.0 ? blinnTerm : 0.0;If the angle between the normal and the light direction is greater than 90
degrees, then we force the specular term to zero. The reason behind this is very
simple: we assume our surface is a closed object. Given that assumption, if the
normal at a location on the surface is facing away from the light, then this could
only happen if there is some other part of the surface between itself and the light.
Therefore, the surface cannot be directly illuminated by that light.That is a reasonable assumption, and it certainly makes sense in reality. But
real-life objects don't have these kinds of hard specular lines. So what are we
missing in our model?What we are missing is that point lights don't exist in the real world. Light
illumination does not come from a single, infinitely small location in space. Even
the size of the Sun relative to Earth has a significant area. So what this means is
that, for a given point on a surface, it could be in partial view of the light
source. Imagine Earth at sunset for an example: part of the sun is below the horizon
and part of it is not.Since only part of the light is visible from that point on the surface, then only
part of the light contributes to the overall illumination. So at these places where
you might get hard specular boundaries, under more real lighting conditions, you
still get a semi-gentle fall-off.That's all well and good, but modeling true area lights is difficult even for
simple cases. A much simpler way to resolve this is to not use such a low specular
exponent. This specular exponent is relatively small, leading to a very broad
specular highlight. If we restrict our use of a specular term to surfaces who's
specular exponent is reasonably large, we can prevent this artifact from
appearing.Here is the same scene, but with a larger exponent:We could also adjust the specular reflectance, so that surfaces with a low
specular exponent also have a small specular reflectance.GaussianPhong and Blinn are nice toy heuristics that take relatively little computational
power. But if you're truly serious about computing specular highlights, you need a model
that actually models microfacets.Real microfacet models are primarily based on the answer to the question What
proportion of the microfacets of this surface are oriented in such a way as to
specularly reflect light towards the viewer? The greater the proportion of
properly oriented microfacets, the stronger the reflected light. This question is
ultimately one of statistics.Thus it makes sense to model this as a probability distribution. We know that the
average microfacet orientation is the surface normal. So it's just a matter of
developing a probability distribution function that says what portion of the surface's
microfacets are oriented to provide specular reflections given the light direction and
the view direction.In statistics, the very first place you go for modelling anything with a probability
distribution is to the normal distribtuion or Gaussian
distribution. It may not be the correct distribution that physically
models what the microfacet distribution of a surface looks like, but it's usually a good
starting point.The Gaussian distribution is the classic bell-shaped curve
distribution. The mathematical function for computing the probability density of the
Gaussian distribution at a particular point X is:Gaussian Distribution FunctionThis represents the percentage of the items in the distribution that satisfy the
property that the X in the distribution is trying to model. The e in
this equation is a common mathematical constant, equivalent to ~2.718. The value of
μ is the average. So the absolute value of X is not important;
what matters is how far X is from the average.The value σ2 is the variance of the
Gaussian distribution. Without getting too technical, the larger this value becomes, the
flatter and wider the distribution is. The variance specifies how far from the average
you can get to achieve a certain probability density. The area of the distribution that
is positive and negative σ away from the average takes up ~68% of the
possible values. The area that is 2σ away represents ~95% of the
possible values.We know what the average is for us: the surface normal. We can incorporate what we
learned from Blinn, by measuring the distance from perfect reflection by comparing the
surface normal to the half-angle vector. Thus, the X values represents the angle between
the surface normal and half-angle vector. The value μ, the average,
is zero.The equation we will be using for modelling the microfacet distribution with a
Gaussian distribution is a slightly simplified form of the Gaussian distribution
equation.Gaussian Specular TermThis replaces our Phong and Blinn terms in our specular lighting equation and gives us
the Gaussian specular model. The value m
ranges from (0, 1], with larger values representing an increasingly rougher surface.
Technically, you can use values larger than 1, but the results begin looking
increasingly less useful. A value of 1 is plenty rough enough for specular reflection;
properly modelling extremely rough surfaces requires additional computations besides
determining the distribution of microfacets.The Gaussian Specular Lighting tutorial shows an implementation of
Gaussian specular. It allows a comparison between Phong, Blinn, and Gaussian. It
controls the same as the previous tutorial, with the H key switching
between the three specular computations, and the ShiftH switching between diffuse+specular and specular only.Here is the fragment shader for doing Gaussian lighting.Gaussian Lighting Shadervec3 lightDir = vec3(0.0);
float atten = CalcAttenuation(cameraSpacePosition, lightDir);
vec4 attenIntensity = atten * lightIntensity;
vec3 surfaceNormal = normalize(vertexNormal);
float cosAngIncidence = dot(surfaceNormal, lightDir);
cosAngIncidence = clamp(cosAngIncidence, 0, 1);
vec3 viewDirection = normalize(-cameraSpacePosition);
vec3 halfAngle = normalize(lightDir + viewDirection);
float angleNormalHalf = acos(dot(halfAngle, surfaceNormal));
float exponent = angleNormalHalf / shininessFactor;
exponent = -(exponent * exponent);
float gaussianTerm = exp(exponent);
gaussianTerm = cosAngIncidence != 0.0 ? gaussianTerm : 0.0;
outputColor = (diffuseColor * attenIntensity * cosAngIncidence) +
(specularColor * attenIntensity * gaussianTerm) +
(diffuseColor * ambientIntensity);Computing the angle between the half-angle vector and the surface normal requires the
use of the acos function. We use the dot-product to compute the
cosine of the angle, so we need a function to undo the cosine operation. The
arc cosine or inverse cosine function
takes the result of a cosine and returns the angle that produced that value.To do the exponentiation, we use the exp function. This function
raises the constant e to the power of the argument. Everything else
proceeds as expected.What Gaussian OffersIf you play around with the controls, you can see how much the Gaussian
distribution offers over Phong and Blinn. For example, set the Gaussian smoothness
value to 0.05.It requires very large exponents, well in excess of 100, to match the small size
and focus of that specular highlight with Phong or Blinn. It takes even larger
exponents to match the Gaussian value of 0.02.Otherwise the differences between Gaussian and Blinn are fairly subtle. For rough
surfaces, there is little substantive difference. But Gaussian tends to have a
sharper, more distinct highlight for shiny surfaces.On PerformanceThe three specular highlight models seen here are obviously more computationally
expensive than diffuse lighting. But which is ultimately more expensive than the
others?The difference between Phong and Blinn is that Phong must compute the reflection
vector, while Blinn computes the half-angle vector. The equation for computing the
reflection vector is:This involves a vector dot product, a scalar multiply, a vector-scalar multiply, and a
vector addition (subtraction). Computing the half-angle vector requires doing a vector
addition and performing a normalize operation. Normalizing a vector requires a vector
dot product (dotting the vector with itself), taking the square-root of that value, and
then a vector-scalar divide by that value.Time once was that it was easy to know what was faster. The presence of a square-root
operation alone would have condemned Blinn as the slower method. On modern 3D graphics
hardware however, taking the reciprocal square-root (1 / √X) is generally about as fast
as doing a vector multiply. This puts Blinn as approximately equal in performance to
Phong; on some hardware, it may even be faster. In general, the performance difference
between the two will be negligible.Gaussian is a different story. It would be reasonable to expect the
pow function, taking xy for arbitrary values, to be slower than executing
exp, ex. They might have the same performance, but if one is going to be
faster, it is more likely to be exp than pow.
However, Gaussian also uses the inverse cosine to compute the angle between the normal
and half-angle vector; that pretty much negates any possibility of performance parity.
The inverse cosine computation is certainly not built into the hardware, and thus must
be computed using the shader logic. And while this is likely true of exponentiation and
power functions, Gaussian has to do two of these operations,
compared to just one for Phong or Blinn.One might consider using Gouraud shading with specular reflections as a method of
optimization. That is, doing per-vertex specular reflections. Since there are fewer
vertices than fragments, this might sound like a good idea. However, this is not for the
best. Specular highlights do not interpolate linearly at all, so unless the mesh is
finely divided, it will generally look awful.In ReviewIn this tutorial, you have learned the following:Specular lighting represents direct, mirror-like reflections from a surface.
Specular highlights are mirror-like reflections directly from a light source.
Adding weak specular highlights to even rough surfaces can increase visual
realism.The microfacet model of specular reflection means that, for a given surface
area, there are many mirror-like surfaces. Each microfacet reflects perfectly in
its direction. The average of the microfacets The Phong and Blinn models of specular reflection use a power function based
on how close the viewer is to perfect reflection to approximate a microfacet
distribution.A Gaussian statistical distribution can be used to more accurately model the
distributions of microfacets on a surface.Further StudyTry doing these things with the given programs.Change the shaders to use the diffuse color as the specular color. You may
need to drop the specular color somewhat to keep from over-brightening the
scene. How this all looks will be particularly evident with the colored
cylinder.Further ResearchAs you might guess, this is far from the end on specular reflections and specular
highlights. Accurately modelling specular reflection is very difficult; doing so
while maintaining high performance is even moreso.If you are interested in more accurate models of specular highlights, there is the
Beckmann distribution. This is a particular statistical distribution of microfacets
that is more physically based than a Gaussian distribution. It may or may not be a
bit more computationally expensive than Gaussian; Beckmann lacks the inverse cosine,
but has more other math to it. The two do have a roughness factor that has the same
range, (0, 1], and the roughness has the same general meaning in both
distributions.If you want to go even farther, investigate the Cook-Torrance model of specular
reflection. It incorporates several terms. It uses a statistical distribution to
determine the number of microfacets oriented in a direction. This distribution can
be Gaussian, Beckmann, or some other distribution. It modifies this result based on
a geometric component that models microfacet self-shadowing and the possibility for
multiple interreflections among a microfaceted surface. And it adds a term to
compensate for the Fresnel effect: an effect where specular reflection from a
surface is more intense when viewed edge-on than directly top-down.GLSL Functions of Notevec reflectvec Ivec NComputes the vector that would be reflected across the normal N
from an incident vector I. The vector result will be normalized
if the input vectors are normalized. Note that I vector is the
vector towards the surface.vec powvec Xvec YRaises X to the power of Y, component-wise.
If a component of X is less than 0, then the resulting value is
undefined. If X is exactly zero, and Y is less
than or equal to 0, then the resulting value is undefined.vec acosvec XReturns the inverse cosine of X, component-wise. This returns
the angle in radians, which is on the range [0, π]. If any component of
X is outside of the [-1, 1] range, then that component of the
result will be undefined. This is because the cosine of a value is always on [-1,
1], so the inverse-cosine function cannot take values outside of this range.vec expvec exponentReturns the value of eexponent, component-wise.Glossaryspecular reflectionA mirror-like reflection of light from a surface. Specular reflections
reflect light; thus, the color the viewer sees is strongly based on the view
angle relative to the light. Specular reflections often do not affect the
color of the incoming light.specular highlightsMirror-like reflections directly from light sources. Since light sources
are brighter than light reflected by other objects, modelling only specular
highlights can provide useful realism without having to model reflections
from light produced by other objects in the scene.angle of view, viewing angleThe angle between the surface normal and the direction to the
viewer/camera.microfacet modelDescribes a surface as a number of flat planes called microfacets. Each
microfacet reflects light using a simple lighting model. The light from a
portion of the surface is simply the aggregate of the light from all of the
microfacets of the surface. The statistical distribution of microfacet
directions on a surface becomes an integral part of the lighting equation.
The normal of a surface at a point is the average normal of the microfacets
of that part of the surface.The microfacet model can be used to model the reflectance characteristics
of rough surfaces.Phong specular modelA simple model for creating specular highlights. It uses a power function
to determine the distribution of microfacets of the surface. The base of the
power function is the cosine of the angle between the view direction and the
direction of perfect reflection along the surface normal. The exponent is an
arbitrary value on the range (0, ∞); large values describe increasingly
shiny surfaces, while small values are for rough surfaces.half-angle vectorThe vector halfway between the direction towards the light and the view
direction. When the half-angle vector is oriented exactly with the surface
normal, then the view direction is oriented along the reflection direction.
For a given light and view direction, it is the direction that the surface
normal would need to be facing for a direct light reflection to go from the
light source to the viewer.Blinn-Phong specular modelA simple model for creating specular highlights. Like standard Phong, it
uses a power function to model the distribution of microfacets. The base of
the power function is the cosine of the angle between the half-angle vector
and the surface normal. The exponent is an arbitrary value on the range (0,
∞); large values describe increasingly shiny surfaces, while small values
are for rough surfaces.Gaussian distribution, normal distributionA common statistical distribution. It defines the familiar
bell-shaped curve, with the average value at the highest
point of the distribution.Gaussian specular modelA model for creating specular highlights. It uses the Gaussian
distribution to model the distribution of microfacets on a surface. It uses
a value to control the distribution; this value ranges on (0, 1], where
small numbers are smooth surfaces and large numbers are rough
surfaces.inverse cosine, arc cosinePerforms the opposite of the cosine function. The cosine function takes
angles and returns a value on the range [-1, 1]. The inverse cosine takes
values on the range [-1, 1] and returns an angle in radians.