TITLE: A Little Paradise NAME: Tom Dahl COUNTRY: USA EMAIL: Thomas.Dahl@compaq.com WEBPAGE: Not yet implemented TOPIC: Sea COPYRIGHT: I SUBMIT TO THE STANDARD RAYTRACING COMPETITION COPYRIGHT. JPGFILE: litpdise.jpg ZIPFILE: litpdise.zip RENDERER USED: Self-written ray tracer TOOLS USED: Self-written object modeling code. Paper and pencil. "Imaging for Windows NT" to convert from 24-bit to 8-bit BMP format; GraphicConverter on the Macintosh to convert from BMP to JPG. RENDER TIME: 11h 43m 11s HARDWARE USED: Pentium Pro 200 MHz, 128MB memory IMAGE DESCRIPTION: I have always loved tropical islands. Here's one that I would like to visit! My only real trip to such a place was a week spent on St. John in the USVI three years ago -- a lovely island. This is my idea of paradise. DESCRIPTION OF HOW THIS IMAGE WAS CREATED: The image was modeled and rendered with tools I've written from scratch over the past 15 years or so. As such, I haven't provided any sample image data files, because everything uses home-brew formats developed in the 1980s. This is my first submission to the IRTC, motivated by a recent surge in ray-tracing interest. I began work on the image in the beginning of August. (This description is a little long, but I hope it's interesting to some of you, given the unique tools used.) The scene was modeled by creating the object geometry with C code which generates a text data file. This data file is then submitted to the ray tracer for rendering. The ray tracer supports a limited suite of primitives (2D triangles, parallelograms, and disks, plus cones and spheres). My modeling tools thus construct everything out of these shapes. I've slowly built up an ad-hoc library of low- to high-level modeling routines, from simple primitives, to things like generalized objects of rotation, to particular objects such as chairs. There are no image maps, bump maps, rasters, height fields, or other canned sources for shapes, colors, etc. Everything in the scene is either directly modeled in 3D geometry or algorithmically generated in the ray tracer. This applies to shapes, textures, reflectivity, etc. Some surface textures and varying colors, for instance, are created via a solid-texture procedural model based on concepts from Ken Perlin (but implemented blind from scratch; he hadn't published his code at the time I wanted it!). (I recently discovered that a clone of my ray tracer was created about 1987 by a former colleague at DEC. He started with a copy of my sources circa that era, and re-wrote it to his liking. He distributed his result as share-ware under the name DBW-render. As one might imagine, this was a very amusing finding for me, made during an internet search a few months ago.) The image was rendered with a minimum of 16 root days per pixel, for spatial anti-aliasing and smooth shadows (which are not very apparent at this image scale). The program computes the standard deviation of the pixel's initial batch of sample rays, and will distribute additional batches until a defined threshold (or fixed ray limit, 128 here) is reached. There is one spherical light source, located about a mile out from the island and scaled to the angular size of the Sun. The horizon is about a half mile away (artistic license). The following sections describe the techniques used to model the major scene elements. The listed counts of primitives from which these elements were constructed are approximate. Exact statistics are listed at the end. (The 'invisibles' are objects given to the ray tracer for the purpose of Phong shading. The island, for instance, is composed of a large expanse of triangles whose surface normals are adjusted via Phong shading. For efficiency, the expanse is hierarchically divided manually into many bounding extents to speed intersection calculations. A given Phong-shaded object primitive is only influenced by its neighbors within the extent; this provides the modeler with a high degree of control. So that adjacent extent's edges would have matching apparent curvature, invisible duplicates of nearby primitives from other extents are specified in the scene. These invisible primitives are not themselves rendered.) The rendering stage consumed about 75MB of memory. (A 1024 x 1024 x 24 bit version of the image in BMP format is included in the ZIP archive. On a display with good color depth it looks nice.) SKY This is a single rectangle, with a procedural color which is based on a 3D marbling model, and given a height-based brightness. WATER (13,000 triangles) FOAM (5,800 spheres) FISH The water surface was very interesting to model. The small-scale ripples are generated in the ray tracer via algorithmic surface-normal perturbation based on a wave-interference model defined by the scene. The long-period waves which come from the lower-right, however, are directly modeled in the scene object geometry. After doing a little research in an oceanography book, I developed a simulation-based approach for determing what the surface height is at an arbitrary point, given a wave source, period, and amplitude, and an ocean-bottom surface contour model. The waves slow and compress as they enter shallow water. This makes the wave-fronts, which begin slightly concave to the lower right, reverse curve around the island. In the island's lee they tend to create a turbulent flow. The water surface is a non-uniform tesselation of 13,000 triangles (denser near the eye), whose vertices are displaced according to the wave simulation results. The foam near shore was a late experiment. It is composed of spheres, whose size and distribution was determined by a probability-density function driven by a wave-interference model similar to that used in the ray tracer for the small ripples. I use this interference technique a lot for many functions which need to vary over distance. It generates smoothly varying deltas, small between close points and arbitrarily large between far points, in a complex and non-repeating manner. The fish are very basic, constructed from a few dozen triangles each, and do not bear close scrutiny! Fortunately the water hides such sins. The sea grass (about 900 triangles) was created with the grass-planting model described below. ISLAND (3,000 triangles) The island itself was modeled in two stages. A basic shape was first created as a simple broad rounded cone. This began as a flat tesselation of about 100 triangles, which was algorithmically deformed into a hump, with modest variable perturbations applied throughout to make it non- uniform. This basic landform was supplied to the wave simulation described above, and is otherwise invisible. A second stage was used to create the visible landform, beginning with a much finer tesselation of about 3,000 triangles (denser near the center, above water). This was draped over the basic landform, and then another interference-deformation model was applied to adjust the tesselation vertices, creating an undulating surface. This was modulated according to height, so that underwater and low-level regions stayed fairly smooth, while central regions became rougher. During ray tracing, the sand's small-scale ripples were algorithmically generated via surface-normal perturbation, according to parameters defined by the scene. Similarly, the faint pink variations in sand color (and obvious darkenings where wet) were computed in the ray tracer according to scene instructions. ROCK (8,000 triangles) The large rocks (two on land, four underwater) were created as collections of triangles. Each is a basic hand-defined six-sided pyramid. The six faces were then recursively subdivided. New intermediate triangle vertices were perturbed using the interference model, with displacement scaled according to recursion level. The color streaks and darker wet areas are generated by the ray tracer according to scene instructions. PALMS (11,000 trianges, 14,000 rectangles, 100 spheres) I spent a moderate amount of time developing the routine which creates palm trees. The trunk consists of spheres stacked in a slightly irregular manner, flared at the base. They are given a wrinkled surface texture in the ray tracer. The fronds are randomly distributed. Each stem is a series of rectangles, and the leaves are triangles generated according to a basic distribution model. The tips of the leaves are displaced using a variation of the interference model, so that adjacent leaves experience similar displacements, but these vary over larger scales. GRASS (2,000 triangles) MOSS (400 spheres) FERNS (27,000 triangles, 2000 cones) VINES (1,400 trianges, 50 cones) The grass was modeled with one triangle per blade, which were given a color fade from base to tip within the ray tracer (difficult to see in this image). The grass clumps were distributed using a probability- density function and then located at the appropriate height of land (with a little ray-tracer in the modeling program to determine surface intersection points). The moss is a collection of spheres, sized and distributed in a manner similar to that used for the grass. (The pebbles on the beach were created with the same code.) The ferns were the last thing I added to the scene, and at this scale are not well represented! A recursive routine was written to create a fern lobe, with sections of cones for the stem and leaves made of triangles. In this scene the ferns use two levels of recursion, so that the basic leaf lobes are themselves composed of a sideways stem and individual leaf buds. The vines were created with code written for a prior project. The stems are cone segments. Each leaf is about 60 triangles, based on a prototype leaf I drew on graph paper and hand-digitized. The plant is built using a recursive routine, with user-defined fall-off parameters and other branching rules. BIRDS Each bird is hand built from about 65 triangles, Phong-shaded together in the ray-tracer. I originally defined the geometry about two years ago, using graph paper and pencil, for another project (part of a Windows screen saver where a wire-frame flock flies around). CHAIR (4,800 triangles) HAMMOCK (600 cylinders, 500 spheres) I created the chair a few months ago for the last image I created (unpublished). I really like this chair. I used graph paper and pencil to lay out the parts, and hand-digitized the outlines off the graph paper. The 2D outlines were used to make 3D extrusions (out of triangles) via code I wrote a couple of years ago; see the Signature section. Most of the triangles in the chair are invisible here, serving to construct the rounded edges of the frame. These triangles were computed algorithmically based on a user-defined champher profile. The hammock was a fun mini-project. I developed a hammock routine which accepts parameters for basic dimensions, desired curvature, and level of detail in the cord web (fairly invisible in this scene). The hammock consists of short cylinders, which form a non-uniform 2D parabolic surface. These are arranged diagonally to create diamond-shape holes. A sphere is located at each intersection to represent a small knot. SIGNATURE (9,000 triangles) I created the font model a couple of years ago for another series of projects. It was a LOT of work, which I will never repeat! I printed out large-scale outlines of the Bookman Bold font on a Macintosh, with an overlaid grid. With a pencil, I then hand-digitized the outlines from the graph paper to define the 2D shape of each printing character in the ASCII set. With repeated fine-tuning, I did about one glyph per day. To create the 3D letterforms, I wrote an algorithm which starts with the 2D surface definition (set of control points, edge connection pairs, and triangle-face-definition triples) and extrudes it in the 3rd dimension. An arbitrary edge champher may be applied. In this scene I used a rounded profile, which accounts for the bulk of the triangles in the signature. The letter objects were positioned partway into the surface of the water, and oriented to be perpendicular to the local surface normal. Spheres in scene: 8328 Triangles in scene: 82835 Quads in scene: 14064 (P)Rings in scene: 5 (P)Cones in scene: 2648 Fractal faces in scene: 0 Invisibles in scene: 26948 Total visible objects: 107880 Total extents: 46693 Total pixels computed: 640000 Total rays traced: 48941772 Average root rays per pixel: 25.13, Max: 128 Average total rays per pixel: 76.47 Max intersections for 1 ray: 64 Total depth sorts: 20914757 Average depth sort size: 2.75 Pre-computation time (dhms) 0:00:01:07 Elapsed time (dhms) 0:11:43:11