kits@6
|
Part01,
Part02,
Part03,
Part04,
Part05,
Part06,
Part07,
Part08,
Part09,
Part10,
Part11,
Part12,
Part13,
Part14,
Part15,
Part16,
Part17,
Part18,
Part19,
|
|
|
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh 'Doc/Guide/running.tex' <<'END_OF_FILE'
X\chapter{Running Rayshade}
X
X{\Rayshade}
Xcan take anywhere from seconds to weeks to render an image. The exact
Xtime required is a function of the speed of the
Xmachine(s) on which
Xyou're working, the complexity of the scene, and how ``good'' you want
Xthe final image to be. \footnote{Appendix D describes some simple
Xways to accelerate the rendering process.}
X
XCreating a finished ray-traced image is an iterative process. Usually, many
Xtest renderings are made at low resolution and with
Xnon-essential features turned off. After each test image is created,
Xsurface definitions might be modified, the eye or look positions may be
Xslightly changed, or the intensity of a light source changed.
X
XThis chapter describes the basic operation of {\rayshade} and some of
Xthe options that control that operation.
XSetting these options properly can greatly reduce
Xrendering time, improve the quality of your images, and make you a better
Xperson.
X
X{\Rayshade} usually works as a filter, reading a description from
Xthe standard input and writing
Xan image file to the standard output. As it is working, {\rayshade} reports
Xon the progress of the rendering by writing messages to the standard
Xerror.
X
X\section{The Input File}
X
XThe scene description read by {\rayshade} consists of a number of
Xkeywords, each followed by a set of arguments. These keywords can
Xbe thought of as commands that direct {\rayshade} to do various things,
Xsuch as create objects, set the eye's position, and change an object's
Xappearance.
X
XMany of the keywords have related command-line options for turning
Xon special features and setting values.
XThese options override the values given in the input file,
Xand are explained in detail in Appendix A.
X
X{\Rayshade} is ``case sensitive,'' which means that typing
X{\tt SPHERE} or {\tt Sphere} instead of {\tt sphere} won't work.
X{\Rayshade} keywords are all lower-case. Many people choose to
Xcapitalize the first letter of names that they give to objects
Xor surfaces in order to make then ``stand out'' in an input file.
X
XKeywords, numbers and strings in the input file are separated by spaces,
Xtabs, or new lines (carriage returns). These ``whitespace'' characters
Xare handled identically by {\rayshade}, which means that you can separate
Xkeywords from keywords, key words from arguments, and arguments from
Xarguments using any combination of whitespace characters that you choose.
X
X\begin{table}
X\centering
X\begin{tabular}{|c|c|l|}\hline\hline
XOperator & Use & Operation \\ \hline \hline
X\verb+^+ & \verb!a ^ b! & Exponentiation \\ \hline
X\verb+-+ & \verb! -a ! & Negation \\ \hline
X\verb+*+ & \verb!a * b! & Multiplication \\ \hline
X\verb+/+ & \verb!a / b! & Division \\ \hline
X\verb+%+ & \verb!a % b! & Remainder \\ \hline
X\verb-+- & \verb!a + b! & Addition \\ \hline
X\verb+-+ & \verb!a - b! & Subtraction \\ \hline \hline
X\end{tabular}
X\caption{Operators, in order of decreasing precedence.}
X\label{tab:operators}
X\end{table}
X
XNumbers may be entered directly as reals or as parenthesized expressions.
XReals may be written in exponential notation if you wish, and
Xintegers may be written with or without a trailing decimal point.
XWhen an integer value is called for and a real is given,
Xthe real value is truncated and the resulting integer is used.
XTable \ref{tab:operators} lists the available operators
Xavailable for use in expressions, in order of decreasing precedence.
X
XThe upshot of all this is that the strings
X{\tt 42}, {\tt 42.},
X{\tt (20 + 22)}, and {\tt (7\verb!^!2 - 7)} mean the same thing
Xto {\rayshade}.
X
XVariables may also be defined and used in expressions. Several
Xbuilt-in functions are also provided. See Appendix B for further details.
X
X{\Rayshade} will automatically run the input it receives
Xthrough the C preprocessor if it is available. This
Xallows you to use C preprocessor directives, such as {\tt \#include},
X{\tt \#define}, and {\tt \#ifdef} when designing your input files.
X
XComments may be included in {\rayshade} input files by enclosing
Xtext between the strings \verb!/*! and \verb!*/!, as in the C
Xprogramming
Xlanguage.
X
X\section{Images}
X
XThe end result of running {\rayshade} is an image file. Depending upon
Xhow it was installed, {\rayshade} writes images in either the Utah Raster
X{\em RLE} format or a generic but easily-manipulated {\em mtv} format
Xused by Mark VandeWettering in his {\em mtv} ray tracer. The {\em mtv}
Xformat consists of a header giving the resolution of the image followed
Xby interleaved red-green-blue values for each pixel. The {\em RLE} format
Xsupports an arbitrary number of color channels,
Xan alpha channel, comments, a history field, and the ability
Xto treat images as windows into a larger image. As a result of this
Xflexibility, a number of {\rayshade}'s features
Xare not
Xsupported if the {\em mtv} format is being used. You are thus strongly
Xencouraged to obtain a copy of the Utah Raster Toolkit.
X
XIf the {\em mtv}
Xformat is used, the image will (and must) consist of three eight-bit
Xcolor channels.
XIf the {\em RLE} format is used, the image file consists of three
Xeight-bit color channels plus an eight-bit alpha channel. {\Rayshade}
Xalso documents in the {\em RLE} header the command line and {\em gamma}
Xvalue used in creating the image.
X
XIf more than one frame is rendered, the resulting images are appended
Xin turn
Xto the image file. The various utilities provided by the
XUtah Raster Toolkit can be used to manipulate the resulting ``movie''
Xfiles.
XIf the Toolkit is not being used, you will probably need to write
Xutility programs to handle the decidedly non-standard multi-image {\em mtv}
Xformat files.
X
XBy default, {\rayshade} writes the computed image to the standard output.
XThe image file may be written to a file instead by specifying a file name
Xin the input stream.
X
X\begin{defkey}{outfile}{{\em filename}}
X Write the computed image to the named file.
X\end{defkey}
XThe output file name may also be specified on the command line by
Xusing the {\tt -O} option.
X
XThe size of the output image is measured in pixels. The {\em x} size
Xis the number of pixels left-to-right, while the {\em y} size is
Xthe number of pixels bottom-to-top.
X
X\begin{defkey}{screen}{{\em xsize ysize}}
X Use a screen {\em xsize} pixels wide by {\em ysize} pixels high.
X\end{defkey}
XThe screen size may also be set on the command line through
Xthe {\tt -R} option.
XThe default
Xscreen size is 512 by 512 pixels.
X
XWhen rendering an image, it is often advantageous to split the image
Xinto a number of disjoint windows, each of which is rendered
Xon a different machine. One then combines the images corresponding to
Xthe windows into a final image.
X
X\begin{defkey}{window}{{\em minx maxx miny maxy}}
X Render the image in the given window.
X\end{defkey}
XThe window must be properly
Xcontained within the screen, i.e., {\em minx} and {\em miny} must
Xbe greater than or equal to zero, while {\em maxx} and
X{\em maxy} must be less than {\em xsize} and {\em ysize}, respectively.
XThe Utah Raster tool
X{\em rlecomp\/} is useful for reconstructing the full image from
Xsub-images.
XBy default, the window
Xis equivalent to the entire screen.
X
XIt is also convenient to be able to render a small portion
Xof the window by specifying a subregion using normalized coordinates.
X
X\begin{defkey}{crop}{{\em left right bottom top}}
X Crop the rendering window.
X\end{defkey}
XThe rendering window is cropped by rendering the screen
Xarea that falls within $minx + left(maxx - minx)$ and
X$minx + right(maxx - minx)$ in the $X$ direction, and similarly
Xfor the $Y$ direction.
X{\em Left} and {\em bottom} must be greater than or equal to zero.
X{\em Right} and {\em top} must be less than or equal to one.
XIf {\em left} is greater than {\em right}, the two values are
Xswapped, and similarly for {\em bottom} and {\em top}.
X
X{\em Gamma correction} may also be applied to the three output color
Xchannels. See Appendix A for more details.
X
X\section{Statistics Reporting}
X
XAs it is working, {\rayshade} informs you of its progress by writing
Xmessages to a ``report file''. By default, the report file is the
Xstandard error. The report itself consists of a number of
Xprogress report lines consisting of the number of eye rays traced,
Xthe total elapsed time, and the elapsed time since the last progress report.
XThe end of the report contains detailed statistics about intersection
Xtests performed, the number of rays traced, and the like.
X
X\begin{defkey}{report}{[{\tt verbose}] [{\tt quiet}] [{\em freq}] [{\em file}]}
X Specify the kind of
X information included in the report and to which
X file it should be written.
X If {\tt verbose} is specified, the
X report will also include a listing of the options selected,
X the
X bounding volumes of each aggregate,
X and the total number of primitives in each aggregate.
X {\tt quiet} causes warning
X messages to be suppressed. {\em freq} specifies the frequency,
X in scanlines rendered, that progress reports are made.
X If given, {\em file} names a file to which the report
X will be written.
X\end{defkey}
XBy default, a non-verbose, non-quiet report is
Xwritten to the standard error once every 10 lines.
XThe {\tt -V} option may also be used to direct the report to a named file.
X
X\section{Antialiasing}
X
XGiven a screen of a fixed size, creating an image is accomplished by
Xsampling each pixel one or more times in order to determine what can
Xbe seen ``through'' that pixel by the camera. A pixel thus covers
Xa square area of the image plane, not just a single point.
X
XIf a pixel is not sampled at the proper rate, aliasing will result.
XAliasing usually appears as ``jaggies'' or ``stair steps'' in the image.
XIn order to reduce these and other artifacts, {\rayshade} provides
Xan adaptive jittered antialiasing scheme that attempts to detect where
Xincreased sampling rates are needed.
XIn jittered sampling, the location at which a sample is taken is
Xperturbed by a random amount. This perturbation reduces aliasing
Xbut adds noise to the image. Appendix B describes how jittered
Xtime sampling is implemented in {\rayshade}.
X
XThe adaptive sampling scheme implemented in {\rayshade} begins
Xby sampling each pixel on the current scanline once.
XFor each pixel on the scanline, the contrast between it and its
Xfour immediate neighbors is computed. If this contrast is greater
Xthan a user-specified maximum in any color channel,
Xthe pixel and its
Xneighbors are all supersampled by firing an additional
X{$numsamples^2 -1$} rays through those pixels that have not already been
Xsupersampled. This process is repeated for the current scanline
Xuntil a pass is made without any
Xpixel being supersampled.
X
X\begin{defkey}{contrast}{{\em redcont greencont bluecont}}
X Set the maximum allowed contrast between four color
X samples when adaptive supersampling is used.
X The contrast test is applied to each color
X channel separately.
X\end{defkey}
XThe default maximum contrast values for the red, green, and blue
Xchannels are 0.25, 0.2, and 0.4, respectively.
X
X\begin{defkey}{sample}{{\em n} [{\tt nojitter}]}
X Use $n^{2} $ samples when performing jittered
X sampling. The maximum legal value is 5.
X If {\tt nojitter} is specified, sample locations
X and times will not be jittered.
X\end{defkey}
XBy default, $3^{2}$ jittered samples are taken.
X
XA given set of sample values must be filtered
Xin order to
Xassign a color to a pixel. Ideally, when performing filtering
Xfor a specific pixel,
Xthe filter will consider samples from neighboring regions. In
X{\rayshade}, the filtering applied to a pixel makes use of samples
Xtaken for that pixel alone. However, one may increase the size
Xof the filter that is applied in order to approximate the results
Xa more robust filtering scheme.
X
X\begin{defkey}{filter}{{\em type} [{\em width}]}
X Use the indicated filter type with the given width,
X in pixels.
X Supported filter types are {\tt gauss} (Gaussian)
X and {\tt box} (the default).
X\end{defkey}
XThe default filter width is 1.0 for a box filter, 1.8 for a Gaussian
Xfilter. The filter and pixel centers always coincide.
XWhen sampling a pixel, samples are taken over the area of
Xthe pixel filter, which is not necessarily the same as the area
Xof the pixel itself.
X
XJittered sampling is used in {\rayshade} to sample extended light
Xsources as well. A total of $samples^2$ samples are taken of
Xeach extended light source in order to determine the extent of shadowing.
X
X\section{The Ray Tree}
X
XWhen ray tracing a scene, reflected or transmitted rays may strike
Xother reflective or transparent objects. Further reflected or
Xtransmitted rays will be spawned, and so on. Taken together, such
Xa family of rays is termed the {\em ray tree}. Care must be taken
Xto control the depth of this tree: If it is allowed to grow too deeply,
Xone may spend a great deal of time computing rays that contribute little
Xto the final picture; if it is not allowed to grow far enough, this
Xpremature tree pruning may be evident in the image.
X
X{\Rayshade} provides two complementary methods for controlling the depth
Xof the ray tree. One method sets an absolute maximum for the tree. The
Xother allows one to adaptively prune a tree as it grows so that ``unimportant''
Xrays are not spawned.
X
X\begin{defkey}{maxdepth}{{\em level}}
X Do not spawn rays deeper than those at the given {\em level}.
X\end{defkey}
XRays from the eye are of depth zero. The default value for
X{\em level} is 15.
XThis depth may also be set from the command line through the {\tt -D} option.
X
X\begin{defkey}{cutoff}{{\em threshold}}
X Do not spawn rays whose contribution to the final color of
X the eye ray is less than {\em threshold} for each color channel.
X Threshold may be given as a single floating-point value,
X or as a red-green-blue triple.
X\end{defkey}
XThe default value is 0.002. This threshold may also be set from
Xthe command line through the {\tt -T} option.
END_OF_FILE
if test 13825 -ne `wc -c <'Doc/Guide/running.tex'`; then
echo shar: \"'Doc/Guide/running.tex'\" unpacked with wrong size!
fi
# end of 'Doc/Guide/running.tex'
fi
if test -f 'Doc/Guide/texture.tex' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Doc/Guide/texture.tex'\"
else
echo shar: Extracting \"'Doc/Guide/texture.tex'\" \(13148 characters\)
sed "s/^X//" >'Doc/Guide/texture.tex' <<'END_OF_FILE'
X\chapter {Texturing}
X
XTextures are used to modify the appearance of an object through the
Xuse of procedural functions. A texture may modify any surface characteristic,
Xsuch as diffuse color, reflectivity, or transparency, or it may
Xmodify the surface normal (``bump mapping'') in order to give the
Xappearance of a rough surface.
X
XAny number of textures may be associated with an object. If more than
Xone texture is specified, they are applied in the order given. This allows
Xone to compose texturing functions and create, for example
Xa tiled marble ground plane using the {\em checker} and {\em marble}
Xtextures.
X
XTextures are associated with objects by following the object specification
Xby a number of lines of the form:
X
X\begin{center}
X{\tt texture} {\em name} $<${\em Texturing Arguments}$>$ [{\em Transformations}]
X\end{center}
X
XTransformations may be applied to the texture in order to, for example,
Xshrink or grow feature size, change the orientation of features, and
Xchange the position of features.
X
XSeveral of the texturing functions take the name of a colormap as an
Xargument. A colormap is 256-line ASCII file, with each line containing
Xthree space-separated values ranging from 0 to 255. Each line gives
Xthe red, green, and blue values for a single entry in the colormap.
X
X\section {Texturing Functions}
X
X\begin{defkey}{blotch}{{\em BlendFactor surface}}
XProduces a mildly interesting blotchy-looking surface.
X{\em BlendFactor} is used to control the interpolation between
Xthe default surface characteristics and the characteristics of
Xthe given surface. A value of 0 results in a roughly 50-50 mix
Xof the two surfaces. Higher values result in a great portion of
Xthe default surface characteristics.
X\end{defkey}
X
X\begin{defkey}{bump}{{\em scale}}
XApply a random bump map. The point of intersection is passed to
X{\em DNoise()}.
XThe returned normalized vector is weighted by {\em scale}
Xand the result is added to the normal vector at the point of intersection.
X\end{defkey}
XUsing an image texture applied to the ``bump'' component offers a more
Xdirect way to control the modification of surface normals (see below).
X
X\begin{defkey}{checker}{$<${\em Surface}$>$}
XApplies a 3D checkerboard texture. Every point that falls within an
X``even'' unit cube will be assigned the characteristics of the named surface
Xapplied to it, while points that fall within ``odd'' cubes will have
Xits usual surface characteristics. Be wary of strange effects due
Xto roundoff error that occur when a planar checkered surface lies
Xin a plane of constant integral value (e.g., $z=0$) in texture space.
XIn such cases,
Xsimply translate the texture to ensure that the planar surface is not
Xcoincident with an integral plane in texture space
X(e.g., {\tt translate 0 0 0.1}).
X\end{defkey}
X
X\begin{defkey}{cloud}{{\em scale H $\lambda$ octaves cthresh lthresh tscale}}
X This texture is a variant on Geoff Gardner's ellipsoid-texturing
X algorithm. It should be applied to unit spheres centered
X at the origin. These spheres may, of course, be transformed
X at will to form the appropriately-shaped cloud or tree.
X
X A sample of normalized {\em fBm} (see the {\em fbm} texture) is
X generated
X at the point of intersection. This sample is used to
X modulate the surface transparency. The final transparency
X if a function of the sample value, the
X the proximity of the point of intersection to the edge of
X the sphere (as seen from the ray origin), and three parameters
X to control the overall ``density.'' The proximity of the point
X to the sphere edge is determined by evaluating a {\em limb} function,
X which varies from 0 on the limb to 1 at the center of the sphere.
X\[
Xtransp = 1. - \frac{fBm - cthresh - (lthresh - cthresh)(1 - limb)}{tscale}
X\]
X\end{defkey}
X
X\begin{defkey}{fbm}{{\em offset scale H $\lambda$ octaves thresh}
X[{\em colormap}]}
XGenerate a sample of discretized fractional Brownian motion (fBm) and
Xuses it to scale the diffuse and ambient component of an object's surface.
X{\em Scale} is used to scale the value
Xreturned by the fBm function. {\em Offset} allows one to control the minimum
Xvalue of the fBm function. {\em H} is the {\em Holder exponent}
Xused in the fBm function (a value of 0.5 works well). $\lambda$ is
Xused to control {\em lacunarity}, and specifies the the frequency
Xdifference between successive samples of the fBm basis function (a
Xvalue of 2.0 will suffice). {\em Octaves} specifies the number of
Xoctaves (samples) to take of the fBm basis function (in this case, Noise()).
XBetween five and seven octaves usually works well. {\em Thresh} is used
Xto specify a lower bound onthe output of the fBm function. Any
Xvalue lower than {\em thresh} is set to zero.
X
XIf a {\em colormap} is named, a 256-entry colormap is read from the named
Xfile, and the sample of fBm is scaled by 255 and is used as an index into
Xthe colormap. The resulting colormap entry
Xis used to scale the ambient and diffuse components of the
Xobject's surface.
X\end{defkey}
X
X\begin{defkey}{fbmbump}{{\em offset scale H $\lambda$ octaves}}
XSimilar to the {\em fbm} texture. Rather than modifying the color of
Xa surface, this texture acts as a bump map.
X\end{defkey}
X
X\begin{defkey}{gloss}{{\em glossiness}}
XGives reflective surfaces a glossy appearance. This texture perturbs
Xthe object's surface normal such that the normal ``samples'' a cone of
Xunit height with radius $1. - glossiness$. A value of 1 results
Xin perfect mirror-like reflections, while a value of 0 results
Xin extremely fuzzy reflections. For best results, jittered sampling
Xshould be used to render scenes that make use of this texture.
X\end{defkey}
X
X\begin{defkey}{marble}{[{\em colormap}]}
XGives a surface a marble-like appearance. The texture is implemented as
Xroughly parallel alternating veins of marble, each of which is
Xseparated by 1/7 of a unit and runs perpendicular to the Z axis.
XIf a colormap is named, the surface's ambient and diffuse colors
Xwill be scaled using the RGB values in the colormap. If no colormap is
Xgiven, the diffuse and ambient components are simply scaled by the
Xvalue of the marble function. One may transform the texture to
Xcontrol the density and orientation of the marble veins.
X\end{defkey}
X
X\begin{defkey}{sky}{{\em scale H $\lambda$ octaves cthresh ltresh}}
X Similar to the {\em fbm} texture. Rather than modifying the
X color of a surface, this texture modulates its transparency.
X {\em cthresh} is the value of the {\em fBm} function above
X which the surface is totally opaque. Below {\em lthresh},
X the surface is totally transparent.
X\end{defkey}
X
X\begin{defkey}{stripe}{$<${\em Surface}$>$ {\em size bump} $<$Mapping$>$}
X Apply a ``raised'' stripe pattern to the surface.
X The surface properties used to color the stripe are those
X of the given surface. The width of the stripe, as compared
X to the unit interval, is given by {\em size}. The magnitude
X of {\em bump} controls the extent to which the bump appears
X to be displaced from the rest of the surface. If negative,
X the stripe will appear to
X sink into the surface; if positive, it will appear to stand
X out of the surface.
X\end{defkey}
XMapping functions are described below.
X
X\begin{defkey}{wood}{}
XGives a surface a wood-like appearance. The feature size of this texture
Xis approximately $0.01$ of a unit, making it often necessary to
Xscale the texture in order to achieve the desired appearance.
X\end{defkey}
X
X\section {Image Texturing}
X
X{\Rayshade} also supports an {\tt image} texture. This texture
Xallows you to use images to modify the characteristics of a surface. You
Xcan use three-channel images to modify the any or all of
Xthe ambient, diffuse, and specular colors of a surface.
XIf you are using the Utah Raster Toolkit,
Xyou can also use single-channel images to modify surface reflectance,
Xtransparency, and the specular exponent. You can also use a single-channel
Ximage to apply a bump map to a surface.
X
XIn all but the bump-mapping case,
Xa component is modified by multiplying the given value by the value
Xcomputed by the texturing function. When using the Utah Raster Toolkit,
Xsurface characteristics are modified in proportion to the value of
Xthe {\em alpha} channel in the image. If there is no {\em alpha} channel,
Xor you are not using the Utah Raster Toolkit, {\em alpha} is assumed to be
Xeverywhere
Xequal to $1$.
X
X\begin{defkey}{component}{$<${\em Component}$>$}
X The named component will be modified.
X\end{defkey}
XPossible surface components are:
X{\tt ambient} (modify ambient color),
X{\tt diffuse} (modify diffuse color),
X{\tt specular} (modify specular color),
X{\tt specpow}, (modify specular exponent),
X{\tt reflect}, (modify reflectivity),
X{\tt transp} (modify transparency),
X{\tt bump}, (modify surface normal).
XThe {\tt specpow}, {\tt reflect}, {\tt transp}, and {\tt bump}
Xcomponents require the use of a single-channel image.
X
X\begin{defkey}{range}{{\em high low}}
X Specify the range of values to which the values in the
X image should be mapped. An value of $1$ will
X be mapped {\em high}, $0$ to {\em low}. Intermediate
X values will be linearly interpolated.
X\end{defkey}
X
X\begin{defkey}{smooth}{}
X When given, pixel averaging will be performed in order
X to smooth the sampled image. If not specified, no averaging
X will occur.
X\end{defkey}
X
X\begin{defkey}{textsurf}{$<${\em Surface Specification}$>$}
X For use when modifying surface colors, this keyword specifies
X that the given surface should be used as the base
X to be modified when the {\em alpha} value in the image
X is non-zero. When {\em alpha} is zero, the object's
X unmodified default surface characteristics are retained.
X\end{defkey}
XThe usual behavior is for the object's default surface properties to
Xbe used.
X
X\begin{defkey}{tile}{{\em un vn}}
X Specify how the image should be tiled (repeated) along the
X $u$ and $v$ axes.
X If positive, the value of {\em un} gives the number of
X times the image should be repeated along the $u$ axis, starting
X from the origin of the texture, and positive {\em vn} gives the
X number of times it
X should be repeated along the $v$ axis. If either value is zero,
X the image is repeated infinitely along the appropriate axis.
X\end{defkey}
XTiling is usually only a concern when planar mapping is being used,
Xthough it may also be used if image textures are being scaled. By default
X{\em un} and {\em vn} are both zero.
X
X
XA mapping function may also be associated with an image texture.
X
X\section {Mapping Functions}
X
XMapping functions are used to apply two-dimensional textures to
Xsurfaces. Each mapping functions defines a different method of transforming
Xa three dimensional point of intersection to a two dimensional $u-v$ pair
Xtermed texturing coordinates.
XTypically, the arguments to a mapping method define a center of
Xa projection and two non-parallel axes that define a local coordinate system.
X
XThe default mapping method is termed $u-v$ mapping or {\em inverse mapping}.
XNormally, there is a different inverse mapping method for each primitive type
X(see chapter 5).
XWhen inverse mapping is used, the point of intersection is passed to
Xthe $uv$ method for the primitive that was hit.
X
X\begin{defkey}{map}{{\tt uv}}
X Use the $uv$ (inverse mapping) method associated with the
X object that was intersected in order to map from 3D to determine
X texturing coordinates.
X\end{defkey}
XThe inverse mapping method for each primitive is described in Chapter 5.
X
X\begin{defkey}{map}{{\tt planar} [\evec{origin} \evec{vaxis} \evec{uaxis}]}
X Use a planar mapping method. The 2D texture is transformed
X so that its $u$ axis is given by \evec{uaxis} and its $v$
X axis by $vaxis$. The texture is projected along the vector
X defined by the cross product of the $u$ and $v$ axes, with
X the (0,0) in texture space mapped to \evec{origin}.
X\end{defkey}
X
X\begin{defkey}{map}{{\tt cylindrical} [\evec{origin} \evec{vaxis} \evec{uaxis}]}
X Use a cylindrical mapping method. The point of intersection
X is projected onto an imaginary cylinder, and the location
X of the projected point is used to determine the texture coordinates.
X If given, \evec{origin} and
X \evec{vaxis} define the cylinder's axis, and \evec{uaxis} defines
X where $u=0$ is located.
X\end{defkey}
XSee the description of the inverse mapping method for the
Xcylinder in Chapter 5. By default, the point of intersection is
Xprojected onto a cylinder that runs through the origin along the $z$
Xaxis, with \evec{uaxis} equal to the $x$ axis.
X
X\begin{defkey}{map}{{\tt spherical} [\evec{origin} \evec{vaxis} \evec{uaxis}]}
X Use a spherical mapping method. The intersection point is
X projected onto an imaginary sphere, and the location of the
X projected point is used to determine the texturing coordinates
X in a manner identical to that used in the inverse mapping method
X for the sphere primitive.
X If given, the center of
X the projection is \evec{origin}, \evec{vaxis} defines
X the sphere axis, and the point where the
X non-parallel \evec{uaxis} intersects the sphere
X defines where $u=0$ is located.
X\end{defkey}
XBy default, a spherical mapping projects points towards the origin,
Xwith \evec{vaxis} defined to be the $z$ axis and
X\evec{uaxis} defined to be the $x$ axis.
END_OF_FILE
if test 13148 -ne `wc -c <'Doc/Guide/texture.tex'`; then
echo shar: \"'Doc/Guide/texture.tex'\" unpacked with wrong size!
fi
# end of 'Doc/Guide/texture.tex'
fi
if test -f 'libray/libobj/triangle.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'libray/libobj/triangle.c'\"
else
echo shar: Extracting \"'libray/libobj/triangle.c'\" \(12047 characters\)
sed "s/^X//" >'libray/libobj/triangle.c' <<'END_OF_FILE'
X/*
X * triangle.c
X *
X * Copyright (C) 1989, 1991, Craig E. Kolb
X * All rights reserved.
X *
X * This software may be freely copied, modified, and redistributed
X * provided that this copyright notice is preserved on all copies.
X *
X * You may not distribute this software, in whole or in part, as part of
X * any commercial product without the express consent of the authors.
X *
X * There is no warranty or other guarantee of fitness of this software
X * for any purpose. It is provided solely "as is".
X *
X * $Id: triangle.c,v 4.0.1.1 91/09/29 15:47:11 cek Exp Locker: cek $
X *
X * $Log: triangle.c,v $
X * Revision 4.0.1.1 91/09/29 15:47:11 cek
X * patch1: Potential roundoff problem in dPdU code.
X *
X * Revision 4.0 91/07/17 14:39:38 kolb
X * Initial version.
X *
X */
X#include "geom.h"
X#include "triangle.h"
X
Xstatic Methods *iTriangleMethods = NULL;
Xstatic char triName[] = "triangle";
X
Xunsigned long TriTests, TriHits;
X
Xstatic void TriangleSetdPdUV();
X
X/*
X * Create and return reference to a triangle.
X */
XTriangle *
XTriangleCreate(type, p1, p2, p3, n1, n2, n3, u1, u2, u3, flipflag)
Xint type;
XVector *p1, *p2, *p3, *n1, *n2, *n3;
XVec2d *u1, *u2, *u3;
Xint flipflag;
X{
X Triangle *triangle;
X Vector ptmp, anorm;
X Float d;
X
X /*
X * Allocate new triangle and primitive to point to it.
X */
X triangle = (Triangle *)share_malloc(sizeof(Triangle));
X triangle->type = type; /* so inttri can tell the difference */
X
X VecSub(*p2, *p1, &triangle->e[0]);
X VecSub(*p3, *p2, &triangle->e[1]);
X VecSub(*p1, *p3, &triangle->e[2]);
X
X /* Find plane normal. */
X VecCross(&triangle->e[0], &triangle->e[1], &ptmp);
X triangle->nrm = ptmp;
X if (VecNormalize(&triangle->nrm) == 0.) {
X RLerror(RL_ADVISE, "Degenerate triangle.\n");
X return (Triangle *)NULL;
X }
X
X if (flipflag)
X VecScale(-1, triangle->nrm, &triangle->nrm);
X
X triangle->d = dotp(&triangle->nrm, p1);
X
X triangle->p[0] = *p1;
X triangle->p[1] = *p2;
X triangle->p[2] = *p3;
X
X if (type == PHONGTRI) {
X if (VecNormalize(n1) == 0. || VecNormalize(n2) == 0. ||
X VecNormalize(n3) == 0.) {
X RLerror(RL_WARN, "Degenerate vertex normal.\n");
X return (Triangle *)NULL;
X }
X triangle->vnorm = (Vector *)Malloc(3 * sizeof(Vector));
X triangle->vnorm[0] = *n1;
X triangle->vnorm[1] = *n2;
X triangle->vnorm[2] = *n3;
X if (flipflag) {
X /* Flip the vertex normals */
X VecScale(-1, triangle->vnorm[0],
X &triangle->vnorm[0]);
X VecScale(-1, triangle->vnorm[1],
X &triangle->vnorm[1]);
X VecScale(-1, triangle->vnorm[2],
X &triangle->vnorm[2]);
X } else if (dotp(&triangle->vnorm[0], &triangle->nrm) < 0.) {
X /*
X * Reverse direction of surface normal on Phong
X * triangle if the surface normal points "away"
X * from the first vertex normal.
X * Note that this means that we trust the vertex
X * normals rather than trust that the user gave the
X * vertices in the correct order.
X */
X RLerror(RL_ADVISE, "Inconsistant triangle normals.\n");
X VecScale(-1., triangle->nrm, &triangle->nrm);
X VecScale(-1., ptmp, &ptmp);
X triangle->d = -triangle->d;
X VecScale(-1., triangle->e[0], &triangle->e[0]);
X VecScale(-1., triangle->e[1], &triangle->e[1]);
X VecScale(-1., triangle->e[2], &triangle->e[2]);
X }
X }
X
X /*
X * If UV coordinates are given for the vertices, allocate and
X * store them.
X */
X if (u1 && u2 && u3) {
X triangle->uv = (Vec2d *)Malloc(3 * sizeof(Vec2d));
X triangle->uv[0] = *u1;
X triangle->uv[1] = *u2;
X triangle->uv[2] = *u3;
X /* Calculate dpdu and dpdv vectors */
X triangle->dpdu = (Vector *)Malloc(sizeof(Vector));
X triangle->dpdv = (Vector *)Malloc(sizeof(Vector));
X TriangleSetdPdUV(triangle->p, triangle->uv,
X triangle->dpdu, triangle->dpdv);
X } else {
X triangle->uv = (Vec2d *)NULL;
X }
X
X /*
X * Find "dominant" part of normal vector.
X */
X anorm.x = fabs(ptmp.x);
X anorm.y = fabs(ptmp.y);
X anorm.z = fabs(ptmp.z);
X
X /*
X * Scale edges by dominant part of normal. This makes intersection
X * testing a bit faster.
X */
X if (anorm.x > anorm.y && anorm.x > anorm.z) {
X triangle->index = XNORMAL;
X d = 1. / ptmp.x;
X } else if (anorm.y > anorm.z) {
X triangle->index = YNORMAL;
X d = 1. / ptmp.y;
X } else {
X triangle->index = ZNORMAL;
X d = 1. /ptmp.z;
X }
X
X VecScale(d, triangle->e[0], &triangle->e[0]);
X VecScale(d, triangle->e[1], &triangle->e[1]);
X VecScale(d, triangle->e[2], &triangle->e[2]);
X
X return triangle;
X}
X
XMethods *
XTriangleMethods()
X{
X if (iTriangleMethods == (Methods *)NULL) {
X iTriangleMethods = MethodsCreate();
X iTriangleMethods->create = (GeomCreateFunc *)TriangleCreate;
X iTriangleMethods->methods = TriangleMethods;
X iTriangleMethods->name = TriangleName;
X iTriangleMethods->intersect = TriangleIntersect;
X iTriangleMethods->normal = TriangleNormal;
X iTriangleMethods->uv = TriangleUV;
X iTriangleMethods->bounds = TriangleBounds;
X iTriangleMethods->stats = TriangleStats;
X iTriangleMethods->checkbounds = TRUE;
X iTriangleMethods->closed = FALSE;
X }
X return iTriangleMethods;
X}
X
X/*
X * Intersect ray with triangle. This is an optimized version of the
X * intersection routine from Snyder and Barr's '87 SIGGRAPH paper.
X */
Xint
XTriangleIntersect(tri, ray, mindist, maxdist)
XTriangle *tri;
XRay *ray;
XFloat mindist, *maxdist;
X{
X Float qi1, qi2, s, k, b0, b1, b2;
X Vector pos, dir;
X
X TriTests++;
X pos = ray->pos;
X dir = ray->dir;
X /*
X * Plane intersection.
X */
X k = dotp(&tri->nrm, &dir);
X if (fabs(k) < EPSILON)
X return FALSE;
X s = (tri->d - dotp(&tri->nrm, &pos)) / k;
X if (s < mindist || s > *maxdist)
X return FALSE;
X
X if (tri->index == XNORMAL) {
X qi1 = pos.y + s * dir.y;
X qi2 = pos.z + s * dir.z;
X b0 = tri->e[1].y * (qi2 - tri->p[1].z) -
X tri->e[1].z * (qi1 - tri->p[1].y);
X if (b0 < 0. || b0 > 1.)
X return FALSE;
X b1 = tri->e[2].y * (qi2 - tri->p[2].z) -
X tri->e[2].z * (qi1 - tri->p[2].y);
X if (b1 < 0. || b1 > 1.)
X return FALSE;
X b2 = tri->e[0].y * (qi2 - tri->p[0].z) -
X tri->e[0].z * (qi1 - tri->p[0].y);
X if (b2 < 0. || b2 > 1.)
X return FALSE;
X } else if (tri->index == YNORMAL) {
X qi1 = pos.x + s * dir.x;
X qi2 = pos.z + s * dir.z;
X b0 = tri->e[1].z * (qi1 - tri->p[1].x) -
X tri->e[1].x * (qi2 - tri->p[1].z);
X if (b0 < 0. || b0 > 1.)
X return FALSE;
X b1 = tri->e[2].z * (qi1 - tri->p[2].x) -
X tri->e[2].x * (qi2 - tri->p[2].z);
X if (b1 < 0. || b1 > 1.)
X return FALSE;
X b2 = tri->e[0].z * (qi1 - tri->p[0].x) -
X tri->e[0].x * (qi2 - tri->p[0].z);
X if (b2 < 0. || b2 > 1.)
X return FALSE;
X } else {
X qi1 = pos.x + s * dir.x;
X qi2 = pos.y + s * dir.y;
X b0 = tri->e[1].x * (qi2 - tri->p[1].y) -
X tri->e[1].y * (qi1 - tri->p[1].x);
X if (b0 < 0. || b0 > 1.)
X return FALSE;
X b1 = tri->e[2].x * (qi2 - tri->p[2].y) -
X tri->e[2].y * (qi1 - tri->p[2].x);
X if (b1 < 0. || b1 > 1.)
X return FALSE;
X b2 = tri->e[0].x * (qi2 - tri->p[0].y) -
X tri->e[0].y * (qi1 - tri->p[0].x);
X if (b2 < 0. || b2 > 1.)
X return FALSE;
X }
X
X tri->b[0] = b0;
X tri->b[1] = b1;
X tri->b[2] = b2;
X
X TriHits++;
X *maxdist = s;
X return TRUE;
X}
X
Xint
XTriangleNormal(tri, pos, nrm, gnrm)
XTriangle *tri;
XVector *pos, *nrm, *gnrm;
X{
X *gnrm = tri->nrm;
X
X if (tri->type == FLATTRI) {
X *nrm = tri->nrm;
X return FALSE;
X }
X
X /*
X * Interpolate normals of Phong-shaded triangles.
X */
X nrm->x = tri->b[0]*tri->vnorm[0].x+tri->b[1]*tri->vnorm[1].x+
X tri->b[2]*tri->vnorm[2].x;
X nrm->y = tri->b[0]*tri->vnorm[0].y+tri->b[1]*tri->vnorm[1].y+
X tri->b[2]*tri->vnorm[2].y;
X nrm->z = tri->b[0]*tri->vnorm[0].z+tri->b[1]*tri->vnorm[1].z+
X tri->b[2]*tri->vnorm[2].z;
X (void)VecNormalize(nrm);
X return TRUE;
X}
X
X/*ARGSUSED*/
Xvoid
XTriangleUV(tri, pos, norm, uv, dpdu, dpdv)
XTriangle *tri;
XVector *pos, *norm, *dpdu, *dpdv;
XVec2d *uv;
X{
X Float d;
X
X /*
X * Normalize barycentric coordinates.
X */
X d = tri->b[0]+tri->b[1]+tri->b[2];
X
X tri->b[0] /= d;
X tri->b[1] /= d;
X tri->b[2] /= d;
X
X if (dpdu) {
X if (tri->uv == (Vec2d *)NULL) {
X *dpdu = tri->e[0];
X (void)VecNormalize(dpdu);
X VecSub(tri->p[0], *pos, dpdv);
X (void)VecNormalize(dpdv);
X } else {
X *dpdu = *tri->dpdu;
X *dpdv = *tri->dpdv;
X }
X }
X
X if (tri->uv == (Vec2d *)NULL) {
X uv->v = tri->b[2];
X if (equal(uv->v, 1.))
X uv->u = 0.;
X else
X uv->u = tri->b[1] / (tri->b[0] + tri->b[1]);
X } else {
X /*
X * Compute UV by taking weighted sum of UV coordinates.
X */
X uv->u = tri->b[0]*tri->uv[0].u + tri->b[1]*tri->uv[1].u +
X tri->b[2]*tri->uv[2].u;
X uv->v = tri->b[0]*tri->uv[0].v + tri->b[1]*tri->uv[1].v +
X tri->b[2]*tri->uv[2].v;
X }
X}
X
Xvoid
XTriangleBounds(tri, bounds)
XTriangle *tri;
XFloat bounds[2][3];
X{
X bounds[LOW][X] = bounds[HIGH][X] = tri->p[0].x;
X bounds[LOW][Y] = bounds[HIGH][Y] = tri->p[0].y;
X bounds[LOW][Z] = bounds[HIGH][Z] = tri->p[0].z;
X
X if (tri->p[1].x < bounds[LOW][X]) bounds[LOW][X] = tri->p[1].x;
X if (tri->p[1].x > bounds[HIGH][X]) bounds[HIGH][X] = tri->p[1].x;
X if (tri->p[2].x < bounds[LOW][X]) bounds[LOW][X] = tri->p[2].x;
X if (tri->p[2].x > bounds[HIGH][X]) bounds[HIGH][X] = tri->p[2].x;
X
X if (tri->p[1].y < bounds[LOW][Y]) bounds[LOW][Y] = tri->p[1].y;
X if (tri->p[1].y > bounds[HIGH][Y]) bounds[HIGH][Y] = tri->p[1].y;
X if (tri->p[2].y < bounds[LOW][Y]) bounds[LOW][Y] = tri->p[2].y;
X if (tri->p[2].y > bounds[HIGH][Y]) bounds[HIGH][Y] = tri->p[2].y;
X
X if (tri->p[1].z < bounds[LOW][Z]) bounds[LOW][Z] = tri->p[1].z;
X if (tri->p[1].z > bounds[HIGH][Z]) bounds[HIGH][Z] = tri->p[1].z;
X if (tri->p[2].z < bounds[LOW][Z]) bounds[LOW][Z] = tri->p[2].z;
X if (tri->p[2].z > bounds[HIGH][Z]) bounds[HIGH][Z] = tri->p[2].z;
X}
X
Xchar *
XTriangleName()
X{
X return triName;
X}
X
Xvoid
XTriangleStats(tests, hits)
Xunsigned long *tests, *hits;
X{
X *tests = TriTests;
X *hits = TriHits;
X}
X
X/*
X * Given three vertices of a triangle and the uv coordinates associated
X * with each, compute directions of u and v axes.
X */
Xstatic void
XTriangleSetdPdUV(p, t, dpdu, dpdv)
XVector p[3]; /* Triangle vertices */
XVec2d t[3]; /* uv coordinates for each vertex */
XVector *dpdu, *dpdv; /* u and v axes (return values) */
X{
X Float scale;
X int hi, mid, lo;
X Vector base;
X
X /* sort u coordinates */
X if (t[2].u > t[1].u) {
X if (t[1].u > t[0].u) {
X hi = 2; mid = 1; lo = 0;
X } else if (t[2].u > t[0].u) {
X hi = 2; mid = 0; lo = 1;
X } else {
X hi = 0; mid = 2; lo = 1;
X }
X } else {
X if (t[2].u > t[0].u) {
X hi = 1; mid = 2; lo = 0;
X } else if (t[1].u > t[0].u) {
X hi = 1; mid = 0; lo = 2;
X } else {
X hi = 0; mid = 1; lo = 2;
X }
X }
X if (fabs(t[hi].u - t[lo].u) < EPSILON) {
X /* degenerate axis */
X dpdv->x = dpdv->y = dpdv->z = 0.;
X } else {
X /*
X * Given u coordinates of vertices forming the
X * 'long' edge, find where 'middle'
X * vertex falls on that edge given its u coordinate.
X */
X scale = (t[mid].u - t[lo].u) / (t[hi].u - t[lo].u);
X VecComb(1.0 - scale, p[lo], scale, p[hi], &base);
X /*
X * v axis extends from computed basepoint to
X * middle vertex -- but in which direction?
X */
X if (t[mid].v < ((1.0 - scale)*t[lo].v + scale*t[hi].v))
X VecSub(base, p[mid], dpdv);
X else
X VecSub(p[mid], base, dpdv);
X (void)VecNormalize(dpdv);
X }
X
X /* sort v coordinates */
X if (t[2].v > t[1].v) {
X if (t[1].v > t[0].v) {
X hi = 2; mid = 1; lo = 0;
X } else if (t[2].v > t[0].v) {
X hi = 2; mid = 0; lo = 1;
X } else {
X hi = 0; mid = 2; lo = 1;
X }
X } else {
X if (t[2].v > t[0].v) {
X hi = 1; mid = 2; lo = 0;
X } else if (t[1].v > t[0].v) {
X hi = 1; mid = 0; lo = 2;
X } else {
X hi = 0; mid = 1; lo = 2;
X }
X }
X if (fabs(t[hi].v - t[lo].v) < EPSILON) {
X /* degenerate axis */
X dpdu->x = dpdu->y = dpdu->z = 0.;
X } else {
X /*
X * Given v coordinates of vertices forming the
X * 'long' edge, find where 'middle'
X * vertex falls on that edge given its v coordinate.
X */
X scale = (t[mid].v - t[lo].v) / (t[hi].v - t[lo].v);
X VecComb(1.0 - scale, p[lo], scale, p[hi], &base);
X /*
X * u axis extends from computed basepoint to
X * middle vertex -- but in which direction?
X */
X if (t[mid].u < ((1.0 - scale)*t[lo].u + scale*t[hi].u))
X VecSub(base, p[mid], dpdu);
X else
X VecSub(p[mid], base, dpdu);
X (void)VecNormalize(dpdu);
X }
X}
X
Xvoid
XTriangleMethodRegister(meth)
XUserMethodType meth;
X{
X if (iTriangleMethods)
X iTriangleMethods->user = meth;
X}
END_OF_FILE
if test 12047 -ne `wc -c <'libray/libobj/triangle.c'`; then
echo shar: \"'libray/libobj/triangle.c'\" unpacked with wrong size!
fi
# end of 'libray/libobj/triangle.c'
fi
echo shar: End of archive 15 \(of 19\).
cp /dev/null ark15isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 19 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
|