rsalz@uunet.uu.net (Rich Salz) (02/08/90)
Submitted-by: Craig Kolb <craig@weedeater.math.yale.edu> Posting-number: Volume 21, Issue 18 Archive-name: rayshade/patch3 System: rayshade version 3.0 Patch #: 3 Priority: MEDIUM Subject: Patch #2, continued. Fix: From rn, say "| patch -p -N -d DIR", where DIR is your rayshade source directory. Outside of rn, say "cd DIR; patch -p -N <thisarticle". If you don't have the patch program, apply the following by hand, or get patch (version 2.0, latest patchlevel). After patching: make depend make If patch indicates that patchlevel is the wrong version, you may need to apply one or more previous patches, or the patch may already have been applied. See the patchlevel.h file to find out what has or has not been applied. In any event, don't continue with the patch. Index: src/patchlevel.h Prereq: 2 1c1 < #define PATCHLEVEL 2 --- > #define PATCHLEVEL 3 Index: src/voxels.c *** src/voxels.c.old Thu Dec 7 23:21:58 1989 --- src/voxels.c Thu Dec 7 23:21:59 1989 *************** *** 18,26 **** * name of the person performing the modification, the date of modification, * and the reason for such modification. * ! * $Id: voxels.c,v 3.0 89/10/27 02:06:09 craig Exp $ * * $Log: voxels.c,v $ * Revision 3.0 89/10/27 02:06:09 craig * Baseline for first official release. * --- 18,29 ---- * name of the person performing the modification, the date of modification, * and the reason for such modification. * ! * $Id: voxels.c,v 3.0.1.1 89/12/06 16:33:29 craig Exp $ * * $Log: voxels.c,v $ + * Revision 3.0.1.1 89/12/06 16:33:29 craig + * patch2: Added calls to new error/warning routines. + * * Revision 3.0 89/10/27 02:06:09 craig * Baseline for first official release. * *************** *** 89,95 **** * in case... */ make_unbounded(obj, grid); ! fprintf(stderr,"Strange, engrid got an unbounded object...\n"); return; } --- 92,98 ---- * in case... */ make_unbounded(obj, grid); ! RSwarning("Strange, engrid got an unbounded object...\n"); return; } Index: doc/rayshade.1 *** doc/rayshade.1.old Thu Dec 7 23:18:57 1989 --- doc/rayshade.1 Thu Dec 7 23:19:01 1989 *************** *** 1,8 **** .\" Manual page for rayshade, 'troff -man' format. .\" ! .\" $Id: rayshade.1,v 3.0.1.1 89/11/17 16:57:19 craig Exp Locker: craig $ .\" .\" $Log: rayshade.1,v $ .\" Revision 3.0.1.1 89/11/17 16:57:19 craig .\" patch1: Documented new -w option. .\" --- 1,38 ---- .\" Manual page for rayshade, 'troff -man' format. .\" ! .\" $Id: rayshade.1,v 3.0.1.11 89/12/06 17:21:39 craig Exp $ .\" .\" $Log: rayshade.1,v $ + .\" Revision 3.0.1.11 89/12/06 17:21:39 craig + .\" patch2: Added suggestion to use cpp. + .\" + .\" Revision 3.0.1.10 89/12/06 16:42:54 craig + .\" patch2: Removed documentation of #include handling. + .\" + .\" Revision 3.0.1.9 89/12/03 17:59:43 craig + .\" patch2: More typos... + .\" + .\" Revision 3.0.1.8 89/12/02 19:52:04 craig + .\" patch2: General cleanup. + .\" + .\" Revision 3.0.1.7 89/12/02 16:48:37 craig + .\" patch2: Documented -F option. + .\" + .\" Revision 3.0.1.6 89/12/02 15:10:09 craig + .\" patch2: Fixed various typos, credited depth of field code. + .\" + .\" Revision 3.0.1.5 89/12/02 14:36:44 craig + .\" patch2: Documented "aperture" and "focaldist". + .\" + .\" Revision 3.0.1.4 89/11/27 18:44:19 craig + .\" patch2: Expanded and corrected the documentation of colormaps. + .\" + .\" Revision 3.0.1.3 89/11/27 18:06:32 craig + .\" patch2: Documented mist, corrected fog documentation & various typos. + .\" + .\" Revision 3.0.1.2 89/11/27 15:20:49 craig + .\" patch2: Corrected heightfield documentation. + .\" .\" Revision 3.0.1.1 89/11/17 16:57:19 craig .\" patch1: Documented new -w option. .\" *************** *** 14,20 **** .TH RAYSHADE 1G "September 11, 1989" .UC 4 .SH NAME ! rayshade \- a raytracing program .SH SYNOPSIS .B rayshade [ --- 44,50 ---- .TH RAYSHADE 1G "September 11, 1989" .UC 4 .SH NAME ! rayshade \- a ray tracing program .SH SYNOPSIS .B rayshade [ *************** *** 25,31 **** .SH DESCRIPTION .I Rayshade reads a file describing a scene to be rendered and produces a ! Utah Raster RLE format file of the raytraced image. .br .SH OPTIONS .TP --- 55,61 ---- .SH DESCRIPTION .I Rayshade reads a file describing a scene to be rendered and produces a ! Utah Raster RLE format file of the ray-traced image. .br .SH OPTIONS .TP *************** *** 38,43 **** --- 68,76 ---- .B \-E \fIeye_separation\fR Set eye separation for stereo imaging. .TP + .B \-F \fIreport_freq\fR + Set frequency, in lines, of status report (default 10). + .TP .B \-h Print a short usage message. .TP *************** *** 87,110 **** .B \-v Write verbose output to standard output. .TP - .B \-w - Write verbose worker information to the standard error. - .TP .B \-W \fIworkers\fR ! Specify number of worker processes (Linda implementation only). .br .SH OVERVIEW .PP .I Rayshade ! is an raytracer capable of raytracing images of objects composed of a large number of primitive objects. ! .I Rayhade reads a series of lines supplied on the standard input or contained in the file named on the command line. After reading the input file, .I rayshade ! raytraces the image from ! the bottom upwards. As each scanline is traced, pixels are written to a Utah Raster RLE format image file. By default, this image file is written to the standard output, and information messages and statistics --- 120,142 ---- .B \-v Write verbose output to standard output. .TP .B \-W \fIworkers\fR ! Specify number of worker processes (Linda version only). ! .TP ! .B \-w ! Write verbose worker information to the standard error (Linda version only). .br .SH OVERVIEW .PP .I Rayshade ! is an ray tracer capable of rendering images composed of a large number of primitive objects. ! .I Rayshade reads a series of lines supplied on the standard input or contained in the file named on the command line. After reading the input file, .I rayshade ! renders the image. As each scanline is rendered, pixels are written to a Utah Raster RLE format image file. By default, this image file is written to the standard output, and information messages and statistics *************** *** 125,138 **** and range from 0 (zero intensity) to 1. (full intensity). .PP - A - .B #include - directive is supported which, as in the C language, - causes the contents of the quoted filename which follows to be read and - effectively inserted at that point in the input file. Be warned that - .I rayshade - does no checking for mutual or recursive inclusion of files. - .PP The following sections describe the keywords which may be included in the input file. Items in boldface type are literals, while square brackets surround optional items. --- 157,162 ---- *************** *** 173,179 **** "-R 128 128" on the command line. .TP \fBscreen \fIx_resolution y_resolution\fR ! Specifies the horizontal and vertical resolution of the image to be traced. This command may be overridden through use of the \fB-R\fR option. The default resolution --- 197,203 ---- "-R 128 128" on the command line. .TP \fBscreen \fIx_resolution y_resolution\fR ! Specifies the horizontal and vertical resolution of the image to be rendered. This command may be overridden through use of the \fB-R\fR option. The default resolution *************** *** 190,195 **** --- 214,245 ---- By default, the image is written to the standard output. This command may be overridden through the use of the \fB-O\fR option. .TP + \fBaperture \fIaperture_radius\fR + The \fIaperture_radius\fR is the radius, in world units, of the aperture + centered at the eye point. + This controls, + in conjunction with \fBfocaldist\fR, the depth of field, + and thus the amount of focus blur present in the final image. + Rays are cast from various places on the + aperture disk towards a point which is + \fIfocal_distance\fR units from the center of the aperture disk. + This causes objects which are \fIfocal_distance\fR units from the eye point + to be in sharp focus. Note that an + \fIaperture_radius\fR of zero causes a pinhole camera model to be used, + and there will be no blurring (this is the default). Increasing the + aperture radius leads to increased blurring. When using + a non-zero aperture radius, it is best to use jittered sampling in order to + reduce aliasing effects. + .TP + \fBfocaldist \fIfocal_distance\fR + Specifies the distance, in world units, from the eye point to the + focal plane. Points which lie in this plane will always be in + sharp focus. By keeping + \fIaperture_radius\fR constant and changing \fIfocal_distance\fR, it is + possible to create a sequence of frames which simulate pulling focus. + By default, \fIfocal_distance\fR is equal to the distance from the eye point + to the look point. + .TP \fBmaxdepth \fImaximum_depth\fR Controls the maximum depth of the ray tree. The default is 3, with eye rays considered to be of depth zero. *************** *** 217,226 **** \fBsamples \fInum_samples\fR Specifies the number of jittered samples. See SAMPLING for details. When specified, this value may be overridden through the use of the ! \fB-S\fR option. The default value is three. .TP \fBcontrast \fIred green blue\fR ! Specifies the maximum allowed contrast between samples in a (sub)pixel before subdivision takes place. See SAMPLING for details. When specified in the input file, these values may be overridden through the use of the \fB-C\fR option. The --- 267,276 ---- \fBsamples \fInum_samples\fR Specifies the number of jittered samples. See SAMPLING for details. When specified, this value may be overridden through the use of the ! \fB-S\fR option. The default value is 3. .TP \fBcontrast \fIred green blue\fR ! Specifies the maximum contrast allowed between samples in a (sub)pixel before subdivision takes place. See SAMPLING for details. When specified in the input file, these values may be overridden through the use of the \fB-C\fR option. The *************** *** 233,239 **** Point sources are specified by a location in world-space and produce shadows with sharp edges. Extended sources are specified by a location and a radius. They produce shadows with "fuzzy" edges ! (penumbrae), but increase ray-tracing time considerably. Directional sources are specified by a direction. A maximum of 10 light sources may be defined. .PP --- 283,289 ---- Point sources are specified by a location in world-space and produce shadows with sharp edges. Extended sources are specified by a location and a radius. They produce shadows with "fuzzy" edges ! (penumbrae), but increase ray tracing time considerably. Directional sources are specified by a direction. A maximum of 10 light sources may be defined. .PP *************** *** 262,268 **** time is increased substantially. Rather than tracing one shadow ray to a light source, multiple rays are traced to various points on the extended source. The extended source ! is approximated by sampling a square grid light sources. See SAMPLING for more details on the sampling of extended light sources. .TP --- 312,318 ---- time is increased substantially. Rather than tracing one shadow ray to a light source, multiple rays are traced to various points on the extended source. The extended source ! is approximated by sampling a square grid of light sources. See SAMPLING for more details on the sampling of extended light sources. .TP *************** *** 302,311 **** specify the diffuse color of the surface. This color, the .I brightness component of each light source whose light strikes the surface, and ! dot product of the incoming ray and the surface normal at the point of intersection ! determine the color which is added to the color of the ray striking ! the surface. .PP .I Sr, sg and --- 352,360 ---- specify the diffuse color of the surface. This color, the .I brightness component of each light source whose light strikes the surface, and ! dot product of the incident ray and the surface normal at the point of intersection ! determine the color which is added to the color of the incident ray. .PP .I Sr, sg and *************** *** 330,336 **** a reflection ray. The color assigned to that ray will be scaled by .I refl ! and added to the color of the surface. .PP .I Transp is --- 379,385 ---- a reflection ray. The color assigned to that ray will be scaled by .I refl ! and added to the color of the incident ray. .PP .I Transp is *************** *** 337,347 **** a floating-point number between 0 and 1 which indicates the transparency of the object. If non-zero, a ray striking the surface will spawn a ray which is transmitted through ! the object, ! and the resulting color of this ray is scaled by ! .I transp ! and added to ! the color of the surface. The direction of the refraction ray is controlled by the .I index parameter, which indicates the index of refraction of --- 386,395 ---- a floating-point number between 0 and 1 which indicates the transparency of the object. If non-zero, a ray striking the surface will spawn a ray which is transmitted through ! the object. ! The resulting color of this transmitted ray is scaled by ! \fItransp\fR and added to the ! color of the incident ray. The direction of the transmitted ray is controlled by the .I index parameter, which indicates the index of refraction of *************** *** 365,373 **** .br .SH PRIMITIVES .PP ! The raytracer is capable of rendering a number of primitive objects. Primitives may be specified inside of an object-definition block, in ! which case it is added to the list of primitives belonging to that object. In addition, primitives may be defined outside of object-definition blocks. Primitives such as these are added to the list of primitives belonging to the World object. See --- 413,421 ---- .br .SH PRIMITIVES .PP ! The ray tracer is capable of rendering a number of primitive objects. Primitives may be specified inside of an object-definition block, in ! which case they are added to the list of primitives belonging to that object. In addition, primitives may be defined outside of object-definition blocks. Primitives such as these are added to the list of primitives belonging to the World object. See *************** *** 379,385 **** to this rule are transparent primitives, for which rayshade uses the dot product of the normal and the incident ray to determine if the ray is entering or exiting the surface, and superquadrics, whose normals ! are never modified due to the nature of the ray/superquadric interesection code. Thus, all non-transparent primitives except superquadrics will in effect be double-sided. .PP --- 427,433 ---- to this rule are transparent primitives, for which rayshade uses the dot product of the normal and the incident ray to determine if the ray is entering or exiting the surface, and superquadrics, whose normals ! are never modified due to the nature of the ray/superquadric intersection code. Thus, all non-transparent primitives except superquadrics will in effect be double-sided. .PP *************** *** 454,468 **** while the top will have radius .I top_radius. .TP ! \fBheightfield \fIfilename\fR Reads height field data from \fIfilename\fR and creates a height square height field of unit size centered at (0.5, 0.5). The binary data in \fIfilename\fR is stored as an initial integer giving the square root of number of data ! points in the file, followed by the data stored as floating-point numbers. The height field is rendered as a surface tessellated by triangles. Non-square height fields may be rendered by setting vertex heights to ! less than or equal to -1000. Triangles which have all vertices less than or equal in altitude to this value are not rendered. .TP \fBbox \fIsurface xcenter ycenter zcenter xsize ysize zsize\fR --- 502,516 ---- while the top will have radius .I top_radius. .TP ! \fBheightfield \fIsurface filename\fR Reads height field data from \fIfilename\fR and creates a height square height field of unit size centered at (0.5, 0.5). The binary data in \fIfilename\fR is stored as an initial integer giving the square root of number of data ! points in the file, followed by altitude (Z) values stored as floating-point numbers. The height field is rendered as a surface tessellated by triangles. Non-square height fields may be rendered by setting vertex heights to ! less than or equal to -1000. Triangles which have any vertex less than or equal in altitude to this value are not rendered. .TP \fBbox \fIsurface xcenter ycenter zcenter xsize ysize zsize\fR *************** *** 496,502 **** the value of .I power, the closer it will resemble the box (with rounded corners). A value greater ! than or equal to one is required for reasonable images. In addition, neither transparent superquadrics nor superquadrics viewed from the interior will rendered correctly. .br --- 544,550 ---- the value of .I power, the closer it will resemble the box (with rounded corners). A value greater ! than or equal to 1 is required for reasonable images. In addition, neither transparent superquadrics nor superquadrics viewed from the interior will rendered correctly. .br *************** *** 536,542 **** .I rayshade. Primitive definitions and object instantiations which do not appear inside an object-definition block are added to this object. When ! performing raytracing, rays are intersected with the objects that make up the World object. .PP Internally, objects are stored by one of two means. By default, --- 584,590 ---- .I rayshade. Primitive definitions and object instantiations which do not appear inside an object-definition block are added to this object. When ! performing ray tracing, rays are intersected with the objects that make up the World object. .PP Internally, objects are stored by one of two means. By default, *************** *** 544,550 **** The constituents of such an object are stored in a simple linked-list. When a ray is intersected with such an object, the ray is tested for intersection with each object in the list. ! While the \fIlist\fR is the default method of object storage, one may emphasize this fact in the input file by including the .B list keyword somewhere within the object-definition block. --- 592,598 ---- The constituents of such an object are stored in a simple linked-list. When a ray is intersected with such an object, the ray is tested for intersection with each object in the list. ! While the list is the default method of object storage, one may emphasize this fact in the input file by including the .B list keyword somewhere within the object-definition block. *************** *** 553,566 **** The grid's total size is calculated by .I rayshade ! and is equal to the bounding box of the entire object. A grid subdivides the space in which an object lies into an array of uniform box-shaped .I voxels. Each voxel contains a linked-list of objects and primitives which ! lie within that voxel. When intersecting a ray with an object whose ! constituents are stored in a grid, the ray is traced incrementally from ! voxel-to-voxel, and the ray is intersected with each object in the linked list of each voxel that is visited. In this way the intersection of a ray with a collection of objects is --- 601,614 ---- The grid's total size is calculated by .I rayshade ! and is equal to the bounding box of the object that is engridded. A grid subdivides the space in which an object lies into an array of uniform box-shaped .I voxels. Each voxel contains a linked-list of objects and primitives which ! lie within that voxel. When intersecting a ray with an object which ! is stored in a grid, the ray is traced incrementally from ! voxel-to-voxel, and the ray is tested for intersected against each object in the linked list of each voxel that is visited. In this way the intersection of a ray with a collection of objects is *************** *** 652,661 **** .TP \fBbump\fI scale\fR applies a random bump map to the surface being textured. The point of ! intersection is passed to DNoise(). The returned normalized vector, weighted by .I scale ! is added to the normal vector at the point of intersection. .TP \fBchecker\fI size surface\fR applies a (3D) checkerboard texture to the object being textured. Every --- 700,709 ---- .TP \fBbump\fI scale\fR applies a random bump map to the surface being textured. The point of ! intersection is passed to DNoise(). The returned normalized vector is weighted by .I scale ! and added to the normal vector at the point of intersection. .TP \fBchecker\fI size surface\fR applies a (3D) checkerboard texture to the object being textured. Every *************** *** 663,669 **** of the named surface. Every point that falls within an "odd" cube will retain its usual surface characteristics. Be warned that strange effects due to roundoff error are possible when the planar surface of an object lies ! in a plane of constant integral values in texture space. .TP \fBblotch \fIblend_factor surface\fR This texture produces a mildly interesting blotchy-looking surface. --- 711,717 ---- of the named surface. Every point that falls within an "odd" cube will retain its usual surface characteristics. Be warned that strange effects due to roundoff error are possible when the planar surface of an object lies ! in a plane of constant integral value in texture space. .TP \fBblotch \fIblend_factor surface\fR This texture produces a mildly interesting blotchy-looking surface. *************** *** 675,682 **** .TP \fBfbm \fIscale offset H lambda octaves thresh\fR [\fIcolormap\fR] This texture generates a sample of discretized fractional Brownian motion (fBm) ! and uses it to modify the diffuse component of an object's color. If no ! \fIcolormap\fR is named, the sample is used to scale the object's diffuse color. If a \fIcolormap\fR name is given, a 256-entry colormap is read from the named file, and the object --- 723,730 ---- .TP \fBfbm \fIscale offset H lambda octaves thresh\fR [\fIcolormap\fR] This texture generates a sample of discretized fractional Brownian motion (fBm) ! and uses it to modify the diffuse and ambient components of an object's color. ! If no \fIcolormap\fR is named, the sample is used to scale the object's diffuse color. If a \fIcolormap\fR name is given, a 256-entry colormap is read from the named file, and the object *************** *** 694,707 **** output of fBm function. Any value lower than \fIthresh\fR is set to zero. .TP \fBfbmbump \fIscale offset H lambda octaves thresh\fR ! This texture is similar to the \fBfBm\fR texture. Rather modifying the ! color of a surface, \fBfBmBump\fR acts as a bump map. .TP \fBmarble\fR [\fIcolormap\fR] This texture gives a surface a marble-like appearance. If the name of a \fIcolormap\fR file is given, the marble will be colored using the RGB values ! in the colormap. If no colormap name is given, the diffuse component of ! the object's surface is simply scaled. One may transform the texture to control the density of the marble veins. .TP \fBwood\fR --- 742,756 ---- output of fBm function. Any value lower than \fIthresh\fR is set to zero. .TP \fBfbmbump \fIscale offset H lambda octaves thresh\fR ! This texture is similar to the \fBfbm\fR texture. Rather modifying the ! color of a surface, \fBfbmbump\fR acts as a bump map. .TP \fBmarble\fR [\fIcolormap\fR] This texture gives a surface a marble-like appearance. If the name of a \fIcolormap\fR file is given, the marble will be colored using the RGB values ! in the colormap. If no colormap name is given, the diffuse and ambient ! components of ! the object's surface are simply scaled. One may transform the texture to control the density of the marble veins. .TP \fBwood\fR *************** *** 712,721 **** 256 lines in length, each line containing three space-separated integers ranging from 0 to 255. The first number on the nth line specifies the red component of the nth entry in the colormap, the second number the green ! component, and the third the blue. .PP It is important to note that more than one texture may be applied to ! a point at any time. In addition to being able to apply more than one texture directly (by supplying multiple "texturing information" lines for a single object), one may instantiate textured objects which, in turn, may be textured or contain instances of objects which are textured, and so on. --- 761,774 ---- 256 lines in length, each line containing three space-separated integers ranging from 0 to 255. The first number on the nth line specifies the red component of the nth entry in the colormap, the second number the green ! component, and the third the blue. The values in the colormap are normalized ! before being used in texturing functions. ! Textures which make use of colormaps ! generally compute an index into the colormap and use the corresponding ! entry to scale the ambient and diffuse components of a surface's color. .PP It is important to note that more than one texture may be applied to ! an object at any time. In addition to being able to apply more than one texture directly (by supplying multiple "texturing information" lines for a single object), one may instantiate textured objects which, in turn, may be textured or contain instances of objects which are textured, and so on. *************** *** 724,738 **** .PP .I Rayshade has the capability of including several kinds of atmospheric effects ! when rendering an image. Currently, one such effect is available: .TP \fBfog\fI thinness red green blue\fR Add global exponential fog with the specified \fIthinness\fR and color. Fog is simulated by blending the color of the fog with the color of ! each ray. The amount of fog color added to a ray is a function of ! the logarithm of the ! distance from the ray origin to the point of intersection divided by ! \fIthinness\fR. .br .SH "SAMPLING" .PP --- 777,803 ---- .PP .I Rayshade has the capability of including several kinds of atmospheric effects ! when rendering an image. Currently, two such effects are available: .TP \fBfog\fI thinness red green blue\fR Add global exponential fog with the specified \fIthinness\fR and color. Fog is simulated by blending the color of the fog with the color of ! each ray. The amount of fog color blended into a ray color is an exponential ! function of the distance from the ray origin to the point of intersection ! divided by \fIthinness\fR. If the distance divided by \fIthinness\fR ! is equal to 1, a ray's new color will be half of the fog color plus half its ! original color. ! .TP ! \fBmist\fI red green blue trans.red trans.green trans.blue zero scale\fR ! Add global low-altitude mist of the specified color. The color of ! a ray is modulated by a fog with density which varies linearly with ! the difference in altitude (Z coordinate) between the ray origin and ! the point of intersection. The three ! trans values specify the transmissivity (thinness) of the mist for ! each of the red, green and blue channels. The base altitude of the ! mist is given by \fIzero\fR, and the apparent height of the mist can ! be controlled by \fIscale\fR, which is used to scale the difference in ! altitude. .br .SH "SAMPLING" .PP *************** *** 748,754 **** the \fBcontrast\fR command. There are separate thresholds for the red, green, and blue channels. If the contrast ! in any of the three is greater than the appropriate treshold value, the pixel is subdivided. The pixel-subdivision process is repeated until either the samples' contrast is less than the threshold or the maximum pixel --- 813,819 ---- the \fBcontrast\fR command. There are separate thresholds for the red, green, and blue channels. If the contrast ! in any of the three is greater than the appropriate threshold value, the pixel is subdivided. The pixel-subdivision process is repeated until either the samples' contrast is less than the threshold or the maximum pixel *************** *** 764,770 **** \fB-S\fR option. The integer following this option specifies the square root of the number of regions. .PP ! Each area light source is, in effect, approximated by a square grid of light sources. The length of each side of the square is equal to the diameter of the extended source. --- 829,835 ---- \fB-S\fR option. The integer following this option specifies the square root of the number of regions. .PP ! Each extended light source is, in effect, approximated by a square grid of light sources. The length of each side of the square is equal to the diameter of the extended source. *************** *** 830,836 **** .IN -8 .fi .PP ! Passing this file to .I rayshade will result in an image of a red reflective sphere sitting on a white ground-plane being written to the standard output. Note that in this case, --- 895,901 ---- .IN -8 .fi .PP ! Passing this input to .I rayshade will result in an image of a red reflective sphere sitting on a white ground-plane being written to the standard output. Note that in this case, *************** *** 908,914 **** .fi could be used to define a very primitive truck-like object. .br ! .SH "MINIMIZING RAYTRACING TIME" .PP Ray tracing is a computationally intensive process, and rendering complex scenes can take hours of CPU time, even on relatively powerful --- 973,979 ---- .fi could be used to define a very primitive truck-like object. .br ! .SH "RENDERING HINTS" .PP Ray tracing is a computationally intensive process, and rendering complex scenes can take hours of CPU time, even on relatively powerful *************** *** 920,926 **** of the image to be rendered. The .B \-P option may be used to reduce the maximum pixel subdivision level. ! A maximum level of 0 will speed raytracing up considerably, but will result in obvious aliasing in the image. By default, a pixel will be subdivided a maximum of one time, giving a maximum of nine rays per pixel total. .PP --- 985,991 ---- of the image to be rendered. The .B \-P option may be used to reduce the maximum pixel subdivision level. ! A maximum level of 0 will speed ray tracing considerably, but will result in obvious aliasing in the image. By default, a pixel will be subdivided a maximum of one time, giving a maximum of nine rays per pixel total. .PP *************** *** 941,949 **** .B maxdepth to a small number. If set to 0, no reflection or refraction rays will be traced. ! Lastly, removing all light sources ! will cause no shadow rays to be traced, but will result in a flat-looking ! image. .PP In addition, judicious use of the \fBgrid\fR command can reduce rendering times substantially. --- 1006,1012 ---- .B maxdepth to a small number. If set to 0, no reflection or refraction rays will be traced. ! Lastly, using the \fB-n\fR option will cause no shadow rays to be traced. .PP In addition, judicious use of the \fBgrid\fR command can reduce rendering times substantially. *************** *** 950,955 **** --- 1013,1024 ---- However, if an object consists of a relatively small number of simple objects, it will likely take less time to simply check for intersection with each element of the object than to trace a ray through a grid. + .PP + The C pre-processor can be used to make the creation and managing of input + files much easier. For example, one can create "libraries" of useful colors, + objects, and viewing parameters by using #define and #include. To use such + input files, run the C pre-processor on the file, and pipe the resulting + text to rayshade. .br .SH FILES .nf *************** *** 960,966 **** .I Rayshade had its beginnings as an "introductory" public-domain ! raytracer written by Roman Kuchkuda. Vestiges of his code may be found in rayshade, particularly in the names of variables and the superquadric code. The first version of --- 1029,1035 ---- .I Rayshade had its beginnings as an "introductory" public-domain ! ray tracer written by Roman Kuchkuda. Vestiges of his code may be found in rayshade, particularly in the names of variables and the superquadric code. The first version of *************** *** 972,978 **** was written during the fall of 1988 by Craig Kolb. The Noise() and DNoise() routines which form the basis of many of the texturing functions were written by Robert Skinner and Ken ! Musgrave. .br .SH "CAVEATS" .PP --- 1041,1047 ---- was written during the fall of 1988 by Craig Kolb. The Noise() and DNoise() routines which form the basis of many of the texturing functions were written by Robert Skinner and Ken ! Musgrave. The depth of field code appears courtesy of Rodney G. Bogart. .br .SH "CAVEATS" .PP *************** *** 994,1000 **** The "Total memory allocated" statistic is the total space allocated by calls to malloc. It is \fInot\fR the memory high-water mark. After the input file is processed, memory is only allocated when refraction ! occurs (to push media onto a stack) and when raytracing height fields (to dynamically allocate triangles). .PP The image produced will always be 24 bits deep. --- 1063,1069 ---- The "Total memory allocated" statistic is the total space allocated by calls to malloc. It is \fInot\fR the memory high-water mark. After the input file is processed, memory is only allocated when refraction ! occurs (to push media onto a stack) and when ray tracing height fields (to dynamically allocate triangles). .PP The image produced will always be 24 bits deep. Index: src/raytrace.c *** src/raytrace.c.old Thu Dec 7 23:21:04 1989 --- src/raytrace.c Thu Dec 7 23:21:06 1989 *************** *** 18,26 **** * name of the person performing the modification, the date of modification, * and the reason for such modification. * ! * $Id: raytrace.c,v 3.0.1.2 89/11/16 20:35:30 craig Exp Locker: craig $ * * $Log: raytrace.c,v $ * Revision 3.0.1.2 89/11/16 20:35:30 craig * patch1: ShadeRay is now called on background rays. * --- 18,35 ---- * name of the person performing the modification, the date of modification, * and the reason for such modification. * ! * $Id: raytrace.c,v 3.0.1.5 89/12/07 22:55:25 craig Exp $ * * $Log: raytrace.c,v $ + * Revision 3.0.1.5 89/12/07 22:55:25 craig + * patch2: Renamed utime and stime to avoid name clashes. + * + * Revision 3.0.1.4 89/12/02 16:41:46 craig + * patch2: Added ReportFreq, reporting of total CPU & split times. + * + * Revision 3.0.1.3 89/12/02 14:42:37 craig + * patch2: Added call to focus_blur_ray() to support depth of field. + * * Revision 3.0.1.2 89/11/16 20:35:30 craig * patch1: ShadeRay is now called on background rays. * *************** *** 61,66 **** --- 70,76 ---- int *SampleNumbers; int SampleNumber; int StartLine = UNSET; + int ReportFreq; /* Frequency of status report */ double RedContrast = UNSET, GreenContrast = UNSET, BlueContrast = UNSET; double SampleSpacing; *************** *** 92,98 **** { #ifdef LINDA extern unsigned long primtests[], primhits[]; ! extern double utime, stime; extern unsigned long EyeRays, ShadowRays, ReflectRays, RefractRays, CacheWorked, CacheFailed, ShadowHits, SuperSampled, BVTests, HitRays; --- 102,108 ---- { #ifdef LINDA extern unsigned long primtests[], primhits[]; ! extern double usertime, systime; extern unsigned long EyeRays, ShadowRays, ReflectRays, RefractRays, CacheWorked, CacheFailed, ShadowHits, SuperSampled, BVTests, HitRays; *************** *** 143,150 **** primhits[j] += hittmp[j]; } in ("timing", ? utmp, ? stmp); ! utime += utmp / (double)Workers; ! stime += stmp / (double)Workers; in("worker", ? int); } #endif --- 153,160 ---- primhits[j] += hittmp[j]; } in ("timing", ? utmp, ? stmp); ! usertime += utmp / (double)Workers; ! systime += stmp / (double)Workers; in("worker", ? int); } #endif *************** *** 160,165 **** --- 170,178 ---- extern unsigned long EyeRays; #ifdef LINDA extern int VerboseWorker; + #else + double usertime, systime, lasttime; + extern int Verbose; #endif switch (JitSamples) { *************** *** 205,211 **** in("result", y, ? out_buf:); if (VerboseWorker) fprintf(stderr,"Supervisor: inned %d\n",y); ! if (y % 10 == 0) fprintf(fstats, "Finished line %d.\n",y); fflush(fstats); outline(out_buf); --- 218,224 ---- in("result", y, ? out_buf:); if (VerboseWorker) fprintf(stderr,"Supervisor: inned %d\n",y); ! if (y % ReportFreq == 0) fprintf(fstats, "Finished line %d.\n",y); fflush(fstats); outline(out_buf); *************** *** 214,225 **** /* * Trace each scanline, writing results to output file. */ for (y = StartLine; y >= 0; y--) { trace_jit_line(y, out_buf); outline(out_buf); ! if (y % 10 == 0) { ! fprintf(fstats,"Finished line %d (%ld rays)\n",y, EyeRays); fflush(fstats); } } --- 227,251 ---- /* * Trace each scanline, writing results to output file. */ + lasttime = 0; for (y = StartLine; y >= 0; y--) { trace_jit_line(y, out_buf); outline(out_buf); ! if (y % ReportFreq == 0) { ! fprintf(fstats,"Finished line %d (%ld rays",y, EyeRays); + if (Verbose) { + /* + * Report total CPU and split times. + */ + get_cpu_time(&usertime, &systime); + fprintf(fstats,", %2.2lf sec,", + usertime+systime); + fprintf(fstats," %2.2lf split", + usertime+systime-lasttime); + lasttime = usertime+systime; + } + fprintf(fstats,")\n"); fflush(fstats); } } *************** *** 270,276 **** extern unsigned long EyeRays; extern FILE *fstats; #ifdef LINDA ! extern int maxlevel, VerboseWorker; #endif /* --- 296,305 ---- extern unsigned long EyeRays; extern FILE *fstats; #ifdef LINDA ! extern int VerboseWorker; ! #else ! double usertime, systime, lasttime; ! extern int Verbose; #endif /* *************** *** 338,346 **** while (inp("result", line, ? out_buf:)) { if (VerboseWorker) fprintf(stderr,"Supervisor: inned %d\n",line); ! if (line % 10 == 0) fprintf(fstats, "Finished line %d.\n",line); ! fflush(fstats); outline(out_buf); if (--line < 0) break; --- 367,376 ---- while (inp("result", line, ? out_buf:)) { if (VerboseWorker) fprintf(stderr,"Supervisor: inned %d\n",line); ! if (line % ReportFreq == 0) { fprintf(fstats, "Finished line %d.\n",line); ! fflush(fstats); ! } outline(out_buf); if (--line < 0) break; *************** *** 349,354 **** --- 379,385 ---- #else line = StartLine + 1; trace_line(line, &pixel_buf[line & 01][0]); + lasttime = 0; /* * Work bottom-to-top, as that's the way Utah-raster wants to * operate. *************** *** 359,367 **** pixel_buf[(line+1) & 01], out_buf); outline(out_buf); ! if(line % 10 == 0) { ! fprintf(fstats,"Finished line %d (%ld rays)\n",line, EyeRays); fflush(fstats); } } --- 390,410 ---- pixel_buf[(line+1) & 01], out_buf); outline(out_buf); ! if(line % ReportFreq == 0) { ! fprintf(fstats,"Finished line %d (%ld rays",line, EyeRays); + if (Verbose) { + /* + * Report total CPU and split times. + */ + get_cpu_time(&usertime, &systime); + fprintf(fstats,", %2.2lf sec,", + usertime+systime); + fprintf(fstats," %2.2lf split", + usertime+systime-lasttime); + lasttime = usertime+systime; + } + fprintf(fstats,")\n"); fflush(fstats); } } *************** *** 499,504 **** --- 542,548 ---- double dist; HitInfo hitinfo; extern Vector scrnx, scrny; + extern double aperture; extern unsigned long EyeRays; extern double TraceRay(); *************** *** 511,516 **** --- 555,568 ---- TopRay.dir.z = firstray.z + x*scrnx.z - y*scrny.z; (void)normalize(&TopRay.dir); + + if (aperture > 0.0) { + /* + * If the aperture is open, adjust the initial ray + * to account for depth of field. + */ + focus_blur_ray(&TopRay); + } /* * Do the actual ray trace. Index: src/setup.c *** src/setup.c.old Thu Dec 7 23:21:12 1989 --- src/setup.c Thu Dec 7 23:21:13 1989 *************** *** 18,26 **** * name of the person performing the modification, the date of modification, * and the reason for such modification. * ! * $Id: setup.c,v 3.0 89/10/27 02:06:03 craig Exp $ * * $Log: setup.c,v $ * Revision 3.0 89/10/27 02:06:03 craig * Baseline for first official release. * --- 18,29 ---- * name of the person performing the modification, the date of modification, * and the reason for such modification. * ! * $Id: setup.c,v 3.0.1.1 89/12/02 16:52:33 craig Exp $ * * $Log: setup.c,v $ + * Revision 3.0.1.1 89/12/02 16:52:33 craig + * patch2: Added code to set default value for ReportFreq. + * * Revision 3.0 89/10/27 02:06:03 craig * Baseline for first official release. * *************** *** 40,46 **** */ setup() { ! extern int maxlevel; extern double hfov, vfov; extern Vector eyep, lookp, up; extern Object *World; --- 43,49 ---- */ setup() { ! extern int maxlevel, ReportFreq; extern double hfov, vfov; extern Vector eyep, lookp, up; extern Object *World; *************** *** 80,85 **** --- 83,89 ---- up.x = UPX; up.y = UPY; up.z = UPZ; + ReportFreq = REPORTFREQ; /* * Kinda yicky, but compatible. Index: src/sphere.c *** src/sphere.c.old Thu Dec 7 23:21:19 1989 --- src/sphere.c Thu Dec 7 23:21:20 1989 *************** *** 18,26 **** * name of the person performing the modification, the date of modification, * and the reason for such modification. * ! * $Id: sphere.c,v 3.0 89/10/27 02:06:04 craig Exp $ * * $Log: sphere.c,v $ * Revision 3.0 89/10/27 02:06:04 craig * Baseline for first official release. * --- 18,29 ---- * name of the person performing the modification, the date of modification, * and the reason for such modification. * ! * $Id: sphere.c,v 3.0.1.1 89/12/06 16:33:35 craig Exp $ * * $Log: sphere.c,v $ + * Revision 3.0.1.1 89/12/06 16:33:35 craig + * patch2: Added calls to new error/warning routines. + * * Revision 3.0 89/10/27 02:06:04 craig * Baseline for first official release. * *************** *** 43,54 **** Sphere *sphere; Object *newobj; Primitive *prim; - extern int Quiet, yylineno; if (r < EPSILON) { ! if (!Quiet) ! fprintf(stderr,"Degenerate sphere (line %d)\n", ! yylineno); return (Object *)0; } --- 46,54 ---- Sphere *sphere; Object *newobj; Primitive *prim; if (r < EPSILON) { ! yywarning("Degenerate sphere.\n"); return (Object *)0; } Index: src/surface.c *** src/surface.c.old Thu Dec 7 23:21:25 1989 --- src/surface.c Thu Dec 7 23:21:26 1989 *************** *** 18,26 **** * name of the person performing the modification, the date of modification, * and the reason for such modification. * ! * $Id: surface.c,v 3.0 89/10/27 02:06:05 craig Exp $ * * $Log: surface.c,v $ * Revision 3.0 89/10/27 02:06:05 craig * Baseline for first official release. * --- 18,29 ---- * name of the person performing the modification, the date of modification, * and the reason for such modification. * ! * $Id: surface.c,v 3.0.1.1 89/12/06 16:33:11 craig Exp $ * * $Log: surface.c,v $ + * Revision 3.0.1.1 89/12/06 16:33:11 craig + * patch2: Added calls to new error/warning routines. + * * Revision 3.0 89/10/27 02:06:05 craig * Baseline for first official release. * *************** *** 50,56 **** * Complain if named surface already exists. */ if ((stmp = get_surface(name)) != (Surface *)0) ! yyerror("Surface redefined."); stmp = (Surface *)Malloc(sizeof(Surface)); stmp->name = strsave(name); --- 53,59 ---- * Complain if named surface already exists. */ if ((stmp = get_surface(name)) != (Surface *)0) ! yyerror("Surface \"%s\" redefined.", name); stmp = (Surface *)Malloc(sizeof(Surface)); stmp->name = strsave(name); *************** *** 91,97 **** stmp = get_surface(name); if (stmp == (Surface *)0) ! yyerror("Undefined surface."); return stmp; } --- 94,100 ---- stmp = get_surface(name); if (stmp == (Surface *)0) ! yyerror("Undefined surface \"%s\".", name); return stmp; } Index: src/texture.c *** src/texture.c.old Thu Dec 7 23:21:40 1989 --- src/texture.c Thu Dec 7 23:21:41 1989 *************** *** 18,26 **** * name of the person performing the modification, the date of modification, * and the reason for such modification. * ! * $Id: texture.c,v 3.0 89/10/27 02:06:05 craig Exp $ * * $Log: texture.c,v $ * Revision 3.0 89/10/27 02:06:05 craig * Baseline for first official release. * --- 18,33 ---- * name of the person performing the modification, the date of modification, * and the reason for such modification. * ! * $Id: texture.c,v 3.0.1.2 89/12/06 16:33:50 craig Exp $ * * $Log: texture.c,v $ + * Revision 3.0.1.2 89/12/06 16:33:50 craig + * patch2: Added calls to new error/warning routines. + * + * Revision 3.0.1.1 89/11/27 18:36:54 craig + * patch2: Removed hardcoded constants in calculation of ambient + * patch2: component in several textures. + * * Revision 3.0 89/10/27 02:06:05 craig * Baseline for first official release. * *************** *** 132,139 **** surf->diff.r *= red; surf->diff.g *= grn; surf->diff.b *= blu; ! ! ScaleColor(0.3, surf->diff, &surf->amb); } /* --- 139,147 ---- surf->diff.r *= red; surf->diff.g *= grn; surf->diff.b *= blu; ! surf->amb.r *= red; ! surf->amb.g *= grn; ! surf->amb.b *= blu; } /* *************** *** 271,278 **** index = 255. * val; if (index > 255) index = 255; if (index < 0) index = 0; ! surf->diff = text->colormap[index]; ! ScaleColor(.2, surf->diff, &surf->amb); } else { ScaleColor(val, surf->diff, &surf->diff); ScaleColor(val, surf->amb, &surf->amb); --- 279,290 ---- index = 255. * val; if (index > 255) index = 255; if (index < 0) index = 0; ! surf->diff.r *= text->colormap[index].r; ! surf->diff.g *= text->colormap[index].g; ! surf->diff.b *= text->colormap[index].b; ! surf->amb.r *= text->colormap[index].r; ! surf->amb.g *= text->colormap[index].g; ! surf->amb.b *= text->colormap[index].b; } else { ScaleColor(val, surf->diff, &surf->diff); ScaleColor(val, surf->amb, &surf->amb); *************** *** 341,347 **** val = Marble(pos); if (text->colormap) { index = (int)(255. * val); ! surf->diff = text->colormap[index]; } else { ScaleColor(val, surf->amb, &surf->amb); ScaleColor(val, surf->diff, &surf->diff); --- 353,364 ---- val = Marble(pos); if (text->colormap) { index = (int)(255. * val); ! surf->diff.r *= text->colormap[index].r; ! surf->diff.g *= text->colormap[index].g; ! surf->diff.b *= text->colormap[index].b; ! surf->amb.r *= text->colormap[index].r; ! surf->amb.g *= text->colormap[index].g; ! surf->amb.b *= text->colormap[index].b; } else { ScaleColor(val, surf->amb, &surf->amb); ScaleColor(val, surf->diff, &surf->diff); *************** *** 359,365 **** fp = fopen(filename, "r"); if (fp == (FILE *)NULL) ! yyerror("Cannot open colormap file."); map = (Color *)Calloc(256, sizeof(Color)); --- 376,382 ---- fp = fopen(filename, "r"); if (fp == (FILE *)NULL) ! yyerror("Cannot open colormap file \"%s\".\n", filename); map = (Color *)Calloc(256, sizeof(Color)); Index: src/viewing.c *** src/viewing.c.old Thu Dec 7 23:21:53 1989 --- src/viewing.c Thu Dec 7 23:21:54 1989 *************** *** 18,26 **** * name of the person performing the modification, the date of modification, * and the reason for such modification. * ! * $Id: viewing.c,v 3.0.1.1 89/11/16 18:24:30 craig Exp Locker: craig $ * * $Log: viewing.c,v $ * Revision 3.0.1.1 89/11/16 18:24:30 craig * patch1: Fixed calculation of dist in Stereo mode. * --- 18,33 ---- * name of the person performing the modification, the date of modification, * and the reason for such modification. * ! * $Id: viewing.c,v 3.0.1.3 89/12/02 14:38:37 craig Exp $ * * $Log: viewing.c,v $ + * Revision 3.0.1.3 89/12/02 14:38:37 craig + * patch2: Added depth of field code, courtesy of Rodney G. Bogart. + * + * Revision 3.0.1.2 89/11/27 19:07:49 craig + * patch2: Changed calculation of scrny when NORLE is defined so images + * patch2: will be rendered top-to-bottom. + * * Revision 3.0.1.1 89/11/16 18:24:30 craig * patch1: Fixed calculation of dist in Stereo mode. * *************** *** 34,54 **** #include "typedefs.h" #include "funcdefs.h" Vector lookp, eyep, up, firstray, scrnx, scrny; double vfov, hfov, Separation; int Xres = UNSET, Yres = UNSET, Stereo; viewing() { Vector gaze; ! double dist, magnitude; vecsub(lookp, eyep, &gaze); firstray = gaze; dist = normalize(&gaze); ! (void)crossp(&scrnx, &gaze, &up); ! (void)crossp(&scrny, &scrnx, &gaze); ! dist *= 2.0; /* * Add stereo separation if desired. --- 41,63 ---- #include "typedefs.h" #include "funcdefs.h" + Vector scrni, scrnj; /* Unit vectors of screen plane. */ Vector lookp, eyep, up, firstray, scrnx, scrny; double vfov, hfov, Separation; + double aperture = 0., focaldist = UNSET; int Xres = UNSET, Yres = UNSET, Stereo; + viewing() { Vector gaze; ! double magnitude, dist; vecsub(lookp, eyep, &gaze); firstray = gaze; dist = normalize(&gaze); ! (void)crossp(&scrni, &gaze, &up); ! (void)crossp(&scrnj, &scrni, &gaze); /* * Add stereo separation if desired. *************** *** 58,83 **** magnitude = -.5 * Separation; else magnitude = .5 * Separation; ! eyep.x += magnitude * scrnx.x; ! eyep.y += magnitude * scrnx.y; ! eyep.z += magnitude * scrnx.z; vecsub(lookp, eyep, &firstray); gaze = firstray; ! dist = 2. * normalize(&gaze); ! (void)crossp(&scrnx, &gaze, &up); ! (void)crossp(&scrny, &scrnx, &gaze); } ! magnitude = dist * tan(deg2rad(0.5*hfov)) / Xres; ! scrnx.x *= magnitude; ! scrnx.y *= magnitude; ! scrnx.z *= magnitude; ! magnitude = dist * tan(deg2rad(0.5*vfov)) / Yres; ! scrny.x *= magnitude; ! scrny.y *= magnitude; ! scrny.z *= magnitude; firstray.x += 0.5*Yres*scrny.x - 0.5*Xres*scrnx.x; firstray.y += 0.5*Yres*scrny.y - 0.5*Xres*scrnx.y; firstray.z += 0.5*Yres*scrny.z - 0.5*Xres*scrnx.z; } --- 67,162 ---- magnitude = -.5 * Separation; else magnitude = .5 * Separation; ! eyep.x += magnitude * scrni.x; ! eyep.y += magnitude * scrni.y; ! eyep.z += magnitude * scrni.z; vecsub(lookp, eyep, &firstray); gaze = firstray; ! dist = normalize(&gaze); ! (void)crossp(&scrni, &gaze, &up); ! (void)crossp(&scrnj, &scrni, &gaze); } ! magnitude = 2. * dist * tan(deg2rad(0.5*hfov)) / Xres; ! scrnx.x = scrni.x * magnitude; ! scrnx.y = scrni.y * magnitude; ! scrnx.z = scrni.z * magnitude; ! magnitude = 2. * dist * tan(deg2rad(0.5*vfov)) / Yres; ! #ifdef NORLE ! magnitude *= -1; ! #endif ! scrny.x = scrnj.x * magnitude; ! scrny.y = scrnj.y * magnitude; ! scrny.z = scrnj.z * magnitude; firstray.x += 0.5*Yres*scrny.x - 0.5*Xres*scrnx.x; firstray.y += 0.5*Yres*scrny.y - 0.5*Xres*scrnx.y; firstray.z += 0.5*Yres*scrny.z - 0.5*Xres*scrnx.z; + + if (focaldist == UNSET) + focaldist = dist; + } + + /* + * Depth of field code courtesy of Rodney G. Bogart. + * + * Adjust the initial ray to account for an aperture and a focal + * distance. The ray argument is assumed to be an initial ray, and + * always reset to the eye point. It is assumed to be unit length. + */ + focus_blur_ray(ray) + Ray *ray; + { + Vector circle_point, aperture_inc; + /* + * Find a point on a unit circle and scale by aperture size. + * This simulates rays passing thru different parts of the aperture. + * Treat the point as a vector and rotate it so the circle lies + * in the plane of the screen. Add the aperture increment to the + * starting position of the ray. Stretch the ray to be focaldist + * in length. Subtract the aperture increment from the end of the + * long ray. This insures that the ray heads toward a point at + * the specified focus distance, so that point will be in focus. + * Normalize the ray, and that's it. Really. + */ + unit_circle_point(&circle_point); + veccomb(aperture * circle_point.x, scrni, + aperture * circle_point.y, scrnj, + &aperture_inc); + vecadd(aperture_inc, eyep, &(ray->pos)); + scalar_prod(focaldist, ray->dir, &(ray->dir)); + vecsub(ray->dir, aperture_inc, &(ray->dir)); + normalize(&ray->dir); + } + + /* + * Find a point on a unit circle which is separated from other random + * points by some jitter spacing. + * + * It should do the above, but the temporary hack below just finds a + * jittered point in a unit square. + */ + unit_circle_point(pnt) + Vector *pnt; + { + /* + * This picks a random point on a -1 to 1 square. The jitter stuff + * is correct enough to avoid excessive noise. An extremely blurry + * bright highlight will look squarish, not roundish. Sorry. + */ + double jit; + extern double SampleSpacing; + extern int Jittered, JitSamples, SampleNumber; + + if (Jittered) { + jit = 2. * SampleSpacing; + + pnt->x = nrand()*jit - 1.0 + (SampleNumber % JitSamples) * jit; + pnt->y = nrand()*jit - 1.0 + (SampleNumber / JitSamples) * jit; + pnt->z = 0.0; + } else { + pnt->x = nrand() * 2.0 - 1.0; + pnt->y = nrand() * 2.0 - 1.0; + pnt->z = 0.0; + } } -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net. Use a domain-based address or give alternate paths, or you may lose out.