screamyGuy
Web 2.0 Logos
THIS is not an article about web 2.0 logos. Rather, it's about the current design trend of highly specular environments. More specifically, text and images sitting on a reflective surface, which is commonly referred to as the wet floor effect (I prefer to call it the mirror table effect because the last thing I want to do is get my logo sopping wet). By generating a logo within a physically accurate stochastic raytracer, I've found that one of the common assumptions used in raster and vector art programs to generate these images is slightly incorrect. The fix is simple and the result is subtle.

Classic Style

The basic effect is demonstrated in the applet at Figure 1 and is representative of most implementations. The mirror effect is easily accomplished by inverting the original on the bottom of the image. Next, most implementations include a fade effect wherein the opacity of the reflection falls off with distance. The reason for this is mostly practical — for a realistic mirror effect, one would need to mirror the entire image vertically, which would occupy too much screen real estate. The alternative, truncating the image, is not altogether too pleasing.
You need to install or enable Java to view this content. Get it from java.com Figure 1. Classic wet floor effect. Dragging the rate slider will affect how quickly the opacity of the reflection falls off. Float allows you to raise the text height to accommodate characters extending below the baseline. Selecting the invert box will toggle between light and dark backgrounds.

Unfortunately, the fade effect is not accurate. It implies that the reflectivity of the material falls off with distance. This is not a common material property. As an example, some sunglasses have graduated reflective surfaces. Wet floors do not display this property. Well, at least mine don't.

A world of mirrors

Of course, image falloff does occur, but the mechanism is through blur, not fading. High school physics taught us that the angle of reflection will be equal to the angle of incidence, but on a macroscopic scale this is only true for very smooth surfaces. If the exact point where a light ray hits is slightly misaligned with the overall surface normal, the reflected ray will be perturbed by an equivalent amount. Figure 2 shows a simple Bidirectional Reflectance Distribution Function, or BRDF. This figure indicates how an incident light ray can be scattered by a surface.
You need to install or enable Java to view this content. Get it from java.com Figure 2. A simple 2D BRDF. The incoming ray (blue) will be reflected somewhere within the outgoing (red) distribution. Altering the shiny slider will affect the glossiness and the amount of possible deflection in the outgoing direction. This BRDF is based on the modified Phong BRDF.

Consider the horizontal black line to be the ground plane and the vertical gray line is the image. The blue incoming ray has struck the ground in front of the image and is reflected towards it. By adjusting the shiny slider, you can see that the point on the ground should represent a large portion of the image in the case of a glossy surface or a single point in the case of a mirror. You might complain that this is backwards — the ray should be coming from a light, reflecting off the image, and diffusing from the surface into our eyes. You are right, but most raytracers trace light backwards through the scene, which is allowed. Remember that the BRDF is bidirectional.

Glossy Surface Style

To approximate this effect, we do not need a raytracer. Instead, we can simulate the blur using a convolution kernel, being certain to make the filter width a function of distance from the image. For convolution kernels, any of the usual suspects will suffice: box, triangle, sinc, or the venerable Gaussian. The interesting addition here would be a kernel based on the cosine function because the modified Phong BRDF shown above is based on the cosine of the angle between the reflected and exitant light angles.

Implementation is fairly trivial: the kernel can be separated into a horizontal and vertical pass. On the horizontal pass, a whole scanline is copied to a buffer. Then the filter width for the line is calculated based on its height and the line is subsequently blurred. The process is repeated vertically when the buffer is copied to the screen. One may be tempted to increase the filter width linearly as the height increases, but this is not necessarily correct: referring to Figure 2, we see that the reflected ray is the hypotenuse of a right triangle, so the convolution kernel would increase non linearly with the reflection angle. In practice, this adjustment is hardly noticeable. An implementation of a glossy approximate reflection is shown in Figure 3.

Figure 3. Glossy floor effect. This applet is very processor intensive, so a screenshot is shown here. Click the image to launch an interactive version.

Comparison

Figure 4 compares the approximations to reference images generated in muRay, a stochastic pathtracer. Note that the convolution based approximations for highly specular reflections are accurate and less noisy than their rendered counterparts. The approximations become less accurate as the surfaces become more diffuse. In fact, the kernel support size had to be doubled here to obtain larger blur values. Also, note that the approximations do not account for transformations due to camera location and angle. These can be seen as height differences in the reflections.
Figure 4. Comparison of raytracer and equivalent approximations. Sub figures a, c, and e were raytracer generated with Modified Phong exponents for glossy surfaces a=5000, c=1000, e=50. Sub figures b, d, and f were generated using the attached Java applet and have rate values set subjectively to match the raytracer references.

Steal this code

Feel free to swipe the applet and put it within your page. Just drop the jar in the root directory and add the following code to your web page. One word of warning, image blurring is processor intensive and your visitors may hate you for it. Several parameters are adjustable: mode 0/1 for classic/glossy effect. Set controls to false to suppress display of the controls. The jar will also run in stand alone mode without a browser.
   
              
<applet code="Base.class" archive="web21.jar"
width="545" height="150">
<PARAM NAME="mode" VALUE="1"> 
<PARAM NAME="text" VALUE="text">                            
<PARAM NAME="invert" VALUE="true">  
<PARAM NAME="controls" VALUE="false">
<PARAM NAME="rate" VALUE="30">
<PARAM NAME="textHeight" VALUE="1">  
You need to install or enable Java to view this content.
Get it from <A HREF="http://java.sun.com">java.com</A>
</applet>

                    

Files

glossy reflector source
brdf viewer source
wallpaper

Copyright © 2006 by Matthew Kozak