ÿþ<HTML> <HEAD><TITLE>Bump Mapping with ps3d</TITLE></HEAD> <BODY BGCOLOR="#FFFFCC" > <H1> Bump Mapping with ps3d </H1> <P><B>Marc Wilson</B><BR>Math 308-101<BR>Term Project, 2003</P> <BR><BR> <B>Contents:</B><BR> <A HREF="#Abstract"> 1. Abstract </A><BR> <A HREF="#Lighting"> 2. The ps3d Lighting Model </A><BR> <A HREF="#Idea"> 3. The Basic Idea </A><BR> <A HREF="#Action"> 4. Bump Mapping In Action </A><BR> <A HREF="#Conclusion"> 5. Conclusion </A><BR> <P><A Name="Abstract"></A><H3>1. Abstract </H3></P> <P> Bump mapping is a way to add surface detail without the need for additional surface geometry. It is accomplished by perturbing the surface normal of each pixel, then evaluating the lighting equation at each pixel. We will investigate this using a 3D extension of PostScript called ps3d.</P> <BR><BR> <P><A NAME="Lighting"></A><H3>2. The ps3d Lighting Model </H3></P> <P>The angle between the light vector and the face's normal vector determines how much a face is shaded. Given a light vector L and a normal vector N (both are assumed to be of length 1), the cosine of the angle A between them is given by cos A= L &#149 N. This returns a number between -1 and 1. A transformation R[-1, 1] => R[0,1] is then applied to this number, which is then used to apply the corresponding shade of gray to the surface. Figures 1 and 2 give examples of this. </P> <P><A HREF="lighting1.eps"><IMG SRC="lighting1.png" BORDER=0 VSPACE=20 HSPACE=20></A><A HREF="lighting2.eps"> <IMG SRC="lighting2.png" BORDER=0 VSPACE=20 HSPACE=20></A></P> <BR><BR> <P><A NAME="Idea"></A><H3>3. The Basic Idea </H3></P> <P>A 3D object is composed of many faces. Each of these has a normal vector, as shown in figure 3. Some objects have more geometric detail such as the object in figure 4. It is possible to perturb the normals of figure 3 so that they look like figure 4 as shown in figure 5. This will give the illusion that figure 5 looks like figure 4, provided that the bumps are "not too high." (We'll see examples of this later.)</P> <P><A HREF="bump1.eps"><IMG SRC="bump1.png" BORDER=0 VSPACE=20 HSPACE=20></A><A HREF="bump2.eps"><IMG SRC= "bump2.png" BORDER=0 VSPACE=20 HSPACE=20></A><A HREF="bump3.eps"><IMG SRC="bump3.png" BORDER=0 VSPACE=20 HSPACE=20></A></P> <BR><BR> <P><A NAME="Action"</A><H3>4. Bump Mapping In Action </H3></P> <P> Since I cannot do per pixel lighting directly, I'm going to do my best to approximate this by constructing each surface as a grid (Figure 6) and then perturb the normal of each cell of the grid (Figure 7) to mimic a simple block pattern. If scaled appropriately, this should be a reasonable approximation of the real thing. What I end up with is a data structure containing 1 pixel by 1 pixel faces and their associated normals, which I have perturbed.</P> <P><A HREF="bump4.eps"><IMG SRC="bump4.png" BORDER=0 VSPACE=20 HSPACE=20></A><A HREF="bump5.eps"><IMG SRC= "bump5.png" BORDER=0 VSPACE=20 HSPACE=20></A></P> <P>Figures 8 through 10 show examples of this simple block pattern. Nifty. Figures 11 through 13 show the same block pattern, only this time it's really rendered as a 3D object, not just on a plane. Figures 10 and 13 highlight the biggest problem with bump mapping. Notice how in Figure 13, the far edge of each block is obscured, Figure 10 just looks flat. If the bump is too high, or viewed from a sharp angle, it becomes pretty obvious that it really is only 2 dimensional. <P><A HREF="blockA.eps"><IMG SRC="blockA.png" BORDER=0 VSPACE=20 HSPACE=20></A><A HREF="blockB.eps"><IMG SRC= "blockB.png" BORDER=0 VSPACE=20 HSPACE=20></A><A HREF="blockC.eps"><IMG SRC="blockC.png" BORDER=0 VSPACE=20 HSPACE=20></A></P> <P><A HREF="block3dA.eps"><IMG SRC="block3dA.png" BORDER=0 VSPACE=20 HSPACE=20></A><A HREF="block3dB.eps"><IMG SRC="block3dB.png" BORDER=0 VSPACE=20 HSPACE=20></A><A HREF="block3dC.eps"><IMG SRC="block3dC.png" BORDER=0 VSPACE=20 HSPACE=20></A></P> <BR><BR> <P><A NAME="Conclusion"</A><H3>5. Conclusion </H3></P> <P>Bump mapping provides a pretty convincing way to add detail to a 3D object provided that the bumps are not too high or that they're not view at a sharp angle. My bump mapping proved to be very slow, and couldn't compete with it's 3D equivalent. This is due primarily to the way the shading was handled. Since I couldn't manipulate pixels directly, I had to approximate them using faces roughly the size of pixels. Therefore, the bump mapped block, which was 18x18 "pixels", had 324 faces to shade versus the real 3D object's 5 faces.</P> <BR><BR> <BR><BR> <P><B><FONT COLOR=#FF0000>NOTE</FONT>:</B> You must have <B>both</B> <A HREF="ps3d.inc">ps3d.inc</A> and <A HREF= "block.inc">block.inc</A> in the same directory as GS itself in order to run blockA.eps, blockB.eps, and blockC.eps. You must have ps3d.inc in the same directory as GS in order to run block3dA.eps, block3dB.eps, and block3dC.eps. <P><B> References:</B></P> <P> Casselman, Dr. W. <U><A HREF="http://www.math.ubc.ca/~cass/graphics/text/www/"> A Manual of Mathematical Illustration </A></U></P> <P> Blinn, J. F. "Simulation of Wrinkled Surfaces", Computer Graphics, Volume 12 (3), pp. 286-292 SIGGRAPH-ACM (August 1978) </P> </BODY> </HTML>