rt User Manual


  1. Table of Contents
    1. Table Of Contents
    2. Command Line Interface
      1. Options
      2. Interactive Mode
      3. Non-Interactive Mode
    3. OpenGL Interface
      1. Window Actions
      2. Menu Commands
    4. File Formats
      1. Scenes
      2. Images
    5. Features
      1. Primitives
      2. Lights
      3. Materials
      4. Cameras / Camera Effects
      5. Ray Casting
      6. Recursive Ray Casting
      7. Super Sampling
      8. Texture-, Bump-, Transparency-, Cutout- Mapping
      9. Constructive Solid Geometry
      10. Procedural Textures
    6. Credits


  2. Command Line Interface
  3. rt recognizes a variety of UNIX-style command line options. When no options are specified, rt will run in interactive mode with default values for all rendering options.

    1. Options


    2. Interactive Mode
    3. If one of the -I or --noninteractive options is not specified first in the list of arguments, rt will run in interactive mode. In this mode, an OpenGL window is created to allow interactive camera placement and setting of render options before raytracing. Any command line arguments that are specified replace the default render options values when in interactive mode, but they can still be changed from within the OpenGL context.

      If the -s options is used, the specified file will be loaded and displayed in polygon mode immediately. The -d option is ignored.

    4. Non-Interactive Mode
    5. If either -I or --noninteractive is the first option supplied to rt, no OpenGL window will be created. Instead, the source file will be read in and raytraced to the destination file, all without requiring any additional user input. This is useful for batch renders or complex scenes. Any command line arguments specified replace the default rendering options in the final image.

      The -s and -d options are required for non-interactive mode.

      The -Q or --quiet options will suppress the printing of progress and options information when running in non-interactive mode, for when silent raytracing is desired. Error messages will still be printed.

    Table Of Contents


  4. OpenGL Interface
  5. The purpose of the OpenGL interface is to allow for rapid development of RAY files for raytracing. Previously, RAY file creation was a long and involved process as obtaining visual results meant raytracing the file. Camera positioning was extremely difficult, because it was non-interactive and required manual editing of the direction and up vectors. The OpenGL interface provided by rt greatly improves this process by providing a quick and interactive means of viewing the scene and positioning the camera. The interface accepts mouse commands within the active window, as well as menu commands via a GLUT popup menu.

    When a RAY file is loaded, it is immediately displayed in the window, polygon rendered using OpenGL, the GLU, and GLUT libraries. This is a facsimile of what the scene looks like, as best as OpenGL is able to approximate. Many effects will look strange, like transparency and CSG, while others will be completely absent, like bump mapping or fisheye lens effects. OpenGL mode exists to allow for more rapid development of scene geometry only - polygon rendering is inherently less powerful than a direct illumination method like raytracing.

    The raytraced iamge will appear in the window in place of the polygon rendered scene after it's been created. When raytracing, if Progressive Rendering is turned on, the raytraced image will appear line by line on top of the OpenGL polygon rendered view of the scene. Some discrepancies may exist in exact object placement - errors of a few pixels are common. We're not sure why this happens, but we wish it didn't.

    The raytraced image will continue to be displayed until the view is changed with the mouse, when polygon mode will be resumed. Once that has happened, the raytraced image is lost. For this reason, it is not recommended to use the OpenGL interface to perform long, complicated renders. Establish a camera position and then raytrace the scene via rt's non-interactive mode.

    1. Window Actions
    2. The mouse and keyboard control various aspects of rt when the window is active.

    3. Menu Commands
    4. Raise the popup menu by clicking and holding with the right mouse button inside the window.



    Table Of Contents


  6. File Formats
  7. rt recognizes a variety of different file formats for input and output. The scene description format is RAY, and the image file formats are BMP and PPM.

    1. Scenes
    2. The RAY file format is a losely defined syntax for scene specifications. It has been tailored to fit our exact needs, and so unfortunately, it isn't a standard format useable in any other modellers or renderers. However, this means it's perfectly suited for the needs of rt and CS155.

      To learn more about the RAY format, read the full specification.

    3. Images
    4. Two image formats are supported by rt - BMP and PPM.

      BMP is Microsoft's raw bitmap format. rt supports writing 24-bit 3-channel BMPs in binary format. For more information on the BMP specification, take a look here or here.

      PPM is a very simple, easy to understand, read, write and edit format for storing 24-bit 3-channel image data. rt supports writing ascii PPMs. For more information on the PPM specification, take a look here.

    Table Of Contents


  8. Features
  9. At well over 10,000 lines, rt has a large number of features to allow fine control over your final raytraced image. Many of these features are implementations of popular rendering algorithms and require a bit of explaining to make the algorithm and design choices clear.

    1. Primitives
    2. rt can raytrace a standard set of 3D shapes: spheres, triangles, cones, cylinders, boxes, and tori. Specification of orientation is not allowed for any primitive - the nature of intersection testing makes such calculations extremely complicated. If a primitive is orientable, the z-axis is used. To acheive more complicated positioning and orientation, group objects are provided, which maintain local coordinates via an arbitrary 4x4 tranformation matrix. Examples of matrices to perform various transformations (translate, rotate, scale) can be found in the OpenGL Programming Guide. Use matrix multiplication to compose multiple simple transformations into a single transformation matrix.

    3. Lights
    4. rt supports a standard set of light sources: directional, point and spot. Area lights are not supported. Directional lights are lights infinitely far away, so all light falling in the scene has uniform direction. Point and spot lights are treated as having no volume, existing somewhere within the scene. Since they have finite distance to objects in the scene, they support attenuation (constant, linear and quadratic). These lights are modelled after OpenGL 1.2's light sources.

    5. Materials
    6. rt supports surface material properties modelled after OpenGL 1.2. A material specification consists of ambient, diffuse, and specular responses, as well as emissive light, shininess and transparency coefficients and a refractive index. Materials are used to determine color and intensity of an intersection point on some shape in the scene. The color at an intersection, also called the excident light at that point, is calculated as follows.

      E = EA + EE + ED + ES + ER + ET
      EA = CA * IA
      ED = CH * CD * D ( IF + IB * ktrans ) * ( 1.0 - ktrans )
      ES = CH * CS * S ( IF )
      ER = CS * ReflectedRay
      ET = CD * ktrans * TransmittedRay

      where

      E = excident light / color at intersection
      EA = excident ambient component
      EE = excident emissive component
      ED = excident diffuse component
      ES = excident specular component
      ER = excident reflected component
      ET = excident transmitted component
      IF = incident light on surface's front
      IB = incident light on surface's back
      CA = material's ambient response
      CD = material's diffuse response
      CS = material's specular response
      CH = light shadow color
      ktrans = material's opacity
      D ( ... ) = calculation of diffuse reflection of incident light
      S ( ... ) = calculation of specular reflection of incident light
      ReflectedRay = excident light calculated at intersection point of reflected recursive ray cast
      TransmittedRay = excident light calculated at intersection point of transmitted recursive ray cast

      CH, the projected color of a shadow from a transparent object, is only taken into account when color projection is turned on. It's calculated by starting at white at the light's position and then following the ray to the intersection point. Along the way, the value is multiplied by the color of any transparent objects encountered along the way. If any opaque objects are encountered, it's set to black. When it reaches the intersection point, the color obtained is the multiplier on the incident light due to occlusions from that light source.

      Material's can have associated with them texture maps, bump maps, transparency maps and cutout maps. Texture maps modulate the diffuse and ambient response of the material. Transparency maps modulate the ktrans of the material. These maps are only applied to a material if the shape using the material has the appropriate option turned on. That is, if a material has a texture specified and a shape uses that material but doesn't have texture mapping turned on, the shape will be rendered without the texture map.

    7. Cameras / Camera Effects
    8. The default camera models a simple pinhole camera. It occupies a point in space and the distance to the image plane in front of it is determined by the half height angle, supplied in the RAY file. There are no near or far clipping planes - any object some positive distance in front of the camera will be rendered. By default there is no focus control and the standard perpespective projection is used.

      Depth of field effects have two controls. The #focal_blur directive in a RAY file sets the focal length and aperture for the camera, while the focal blur rays setting sets the number of camera rays to cast. The effect is implemented by jittering the camera's position and direction about some focal point in the scene. The camera is displaced from its position by some random amount and then rotated to point at the focus. for each ray normally cast through a pixel, multiple rays are cast with by the jittered camera. When combined with Super Sampling, the total number of rays cast through each pixel is the number of focal blur rays times the number of jitter rays. Increasing the number of focal blur rays drastically increases the length of time of the render.

      rt can also render images with a fisheye lens effect. The fisheye lens angle specifies how large the viewing area should be, in degrees from the camera's direction. The allowable range for this setting is between 0 and 180. The final rendered image will not be rectangular, depending on the viewing angle. The most common use is 90 degrees to get a hemisphere view of the entire scene in front of the camera, which results in a circular image. The equations used to do the projection calculation can be found here.

    9. Ray Casting
    10. To generate the final rendered image, rays are cast through each pixel of the image, which is a plane in front of the camera, perpendicular to the camera's direction vector. Cast rays are then intersected with the scene. This is handled by the scene heirarchy - each RAY file has a top-level group which every object in the file is contained in. A ray is intersected with the scene by intersecting it with this group. Groups handle intersection testing by transforming the ray from global coordinates to its local coordinates, and then intersecting the ray with each shape within the group. Individual shape primitives handle intersection testing according to their geometry. Thus, a ray is recursively intersected with the entire scene thanks to the recursive nature of the scene heirarchy.

      The intersection process is sped up by the addition of bounding boxes. Each group maintains it's own bounding box, defined as the sum of all the bounding boxes of the objects contained inside it. When testing ray intersection, the ray is first testing against the bounding box - if the test succeeds, the ray is intersected with the group's objects normally, but if the test fails, the intersection test immediately fails. This optimization relies on good use of group directives in the RAY file to group spatially-near objects together; otherwise, the bounding box tests will not provide a significant speed increase, and could potentially slow things down.

      A more reliable optimization on the intersection testing process is the use of octrees (or any other space-partitioning data structure, such as a BSP tree). An octree is a container that can either hold a list of objects or eight child octrees. A global octree is first constructed and all the objects in the scene are added to it (for simplification of computation, objects' bounding boxes are used). If the octree's edge length is greater than some threshold, or the number of objects inside the octree is greater than another threshold, the octree subdivides itself and places all its objects into one (or more) of its eight child octrees. This process is recursed until the space is adequately partitioned. Once the octree is constructed, intersection testing can carry on the same as it did before - the ray is intersected with the top-level octree, and if it passes, the ray is then intersected with everything inside it (either objects, or other octrees). The use of octrees for an average case scene (without pathological placement of objects) will turn the otherwise linear intersection test process into a logarithmic one. For more information on octrees, take a look here.

    11. Recursive Ray Casting
    12. rt has two mechanisms for controlling the number of levels of recursively cast rays (used to calculate reflection and transmission). The first is the recursive depth setting, which defaults to 0. This value is the maximum level of recursion that will be calculated. For example, if recursive depth is set to 1, at most one reflection ray and one transmission ray will be cast from the intersection point found by the original ray cast from the camera. These rays are only cast when they might be used in the calculation - that is, if a material is 100% opaque, no transmition ray will be cast. Similary, if a material is 100% diffuse, no reflection ray will be cast.

      The other mechanism rt supplies to limit the level of recursion is the contribution limit setting. Each recursive ray cast has a smaller and smaller influence on the final color of the image pixel, because of the multipliers on the ray's return value (a reflected ray is multiplied by the material's specular color, and a transmitted ray is multiplied by the material's ktrans). Eventually, recursive rays will have an insignificant influence and their calculation is a waste of time. The contribution limit is the threshold that determines when a recursive ray's contribution to the final pixel color is insignificant. If contribution limit is 0.1 and a material's ktrans is 0.01, then even if the maximum recursive depth hasn't been reached, no recursive transmitted ray will be cast because it's maximum contribution is 0.01 and that's less than the contribution limit. The default contribution limit is 0, which means there is no limit and recursive rays will be cast exhaustively. Depending on the materials in a scene and the recursive depth setting, there may be drastic improvements in rendering times if the contribution limit is set to something like 0.01 or 0.05.

    13. Super Sampling
    14. rt implements super sampling (jittering) as an anti-aliasing technique. Rather than casting a single ray through the center of each pixel in the image, multiple rays are cast, randomly through the pixel and the color values are averaged together. This reduces the aliasing artifacts from a regular sample rate by making the samples irregular within the pixel. Of course, increasing the number of rays cast per pixel drastically increases the total render time. Jitter values around 10 provide good results. When jittering is combined with the depth of field effect, the total number of rays cast through each pixel is the number of focal blur rays times the number of jitter rays.

      rt also uses super sampling to simulate the soft shadows generated by real lights. Modelling a light source as a point with no volume means that it produces sharp shadows - any point in space is very clearly in or out of shadow with respect to the light. Real lights have some volume and so a point in space can be totally in or totally out of its shadow, or partially shadowed, where some but not all of the light source's volume is visible to the point. To simulate this effect, rather than cast a single shadow ray for each light, rt can cast multiple rays jittered about the light source's position, test each one for visibility, and return a number indicating what percentage of the sources' light is visible. Increasing the number of shadow rays cast has a large effect on the total render time. Values around 10 provide good results. This has no effect on directional lights - they still produce sharp shadows. It's possible to jitter the directional light's direction vector and cast multiple shadow rays, but that feature was left out of rt.

    15. Texture-, Bump-, Transparency-, Cutout- Mapping
    16. If a texture map is used on a shape, it will determine the color at any point on that shape's surface. This color can either be retrieved from an image file or determined by some procedural method. If an image file is used, it must be parameterized onto the surface. If a procedural texture is used, then the color value can simply be computed from the location of the point in question.

      In cutout mapping, rt actually removes pieces of the surface of an object. If the map is being done with an image file, it's parameterized onto the surface just as it would be for texture-mapping. For procedural mapping, we simply calculate the color for any given point on the surface. In either case, the intensity of the color value of the map for a point on the surface is used to determine whether a point should be considered part of the surface. If the intensity is less than 0.5, then the point will not be considered a valid intersection. Otherwise, it remains part of the shape.

      For transparency mapping, the intensity is calculated in the same manner that it is for cutout mapping. Rather than actually removing pieces of the surface, we use this intensity to determine the transparency of the shape at this point. If the intensity of the color is 1.0, the surface will be entirely opaque. If the intensity is 0.0, the surface will be entirely transparent.

      In bump-mapping, the normal vector is skewed based on the color gradient of the map around the sample point. For the following explanation, (aside from a few special cases), the "up" vector is considered to be a unit vector in the z-direction, and the "right" vector is computed by crossing the up-vector with the normal.

      If the map is being computed from an image file, then the image coordinates are calculated just as they are for texture-mapping. rt obtains the intensity of the four pixels surrounding the sample point. The change in intensity in the x-direction is used to scale the right-vector, and the change in y-intensity is used to scale the up-vector. Both of these changes are scaled by the value specified with the shape being bump-mapped, with the result being added to the normal vector.

      If, instead, procedural bump-mapping's being done, then the gradient is computed in the x-, y-, and z-directions. (The choice of some offset for the sampling to compute the gradient is arbitrary. For a point (x, y, z) rt looks at (x +/- 0.05, y +/- 0.05, z +/- 0.05) and calculates intensity at each point.) The normal is skewed as before, however it is also skewed by adding in the z-gradient times the cross-product of the up and right vectors.

    17. Constructive Solid Geometry
    18. The CSG interface supports four binary operations and one unary operation. These are:

      Objects a and b may be simple primitives, groups, macro instances, or rayfile instances.

      A CSG object will only be visible at points on the surfaces of its member primitives. Thus, if the Inv operation is used to create an unbounded CSG volume (for instance, trying to draw the complement of a sphere) results may not be what was expected.

      The CSG object is rendered by intersecting the cast ray with each of its primitives. The closest of these intersections is then tested to see whether it's a valid point in the CSG volume. If not, it's discarded and a ray is cast recursively from the point of intersection. This will repeat until either a valid intersection is found or the ray has passed through the CSG object. Material properties for the intersection are those of the primitive which had the first valid intersection. An alternative would be to allow the CSG object to have its own material specification, and to ignore the materials of the shapes contained within - however, this limits the possibilities for the sort of images a CSG object can create.

      Note: "open" cylinders and cones - those without endcaps - are treated as solid volumes for the purposes of CSG.

    19. Procedural Textures
    20. Procedural texturing in rt makes use of color gradients to determine the color of an object. A gradient is specified as a set of pairs, mapping real numbers to an RGB colors. Given any real number, rt can look in the gradient table to determine where it falls, then do linear interpolation between neighbors to determine the color to use. Given the gradient

        #grad_begin -n g1 --
          0.0   0.0 0.0 0.0
          0.5   0.0 0.0 1.0
          1.0   0.0 1.0 0.0
        #grad_end
      

      a value of 0.0 would produce black, 0.25 medium blue, 0.5 bright blue, 0.75 blue-green, and 1.0 green.

      The procedural textures in rt are based on coherent noise functions designed by Ken Perlin. A color gradient must be defined for the texture, and a summation function may optionally be specified as well. (The summation function should take only one variable.)

      The noise functions produce noise in one, two, three, or four dimensions that is locally smooth (no discontinuities). Perlin's original source for the noise functions can be found here. For an explanation of the underlying math, check here. Hugo Elias' websote provides a good explanation of how to use this coherent noise to create interesting textures.

      The noise functions used will return a value in the interval [-1, 1]. rt uses this to generate an output value for a specified persistence and number of octaves. Given a function that returns a noise value for a point (x, y, z), this value is:

      >
      Perlin (x, y, z) {
      sum = 0;
      sum_amplitudes = 0;
      for (i = 0; i < octaves; ++i)
        {
          frequency = 2^i;
          amplitude = persistence^i;
      
          if (doing standard summation)
            sum += noise(x * frequency, y * frequency, z * frequency) * amplitude;
          else // a function has been defined for the summation
            sum += function(noise(x * frequency, y * frequency, z * frequency)) * 
              amplitude;
      
          sum_amplitudes += amplitude;
        }
        return sum / sum_amplitude;
      }
      

      The value computed here is then used as a lookup in the gradient to determine the color to be used at (x, y, z).

    Table Of Contents


  10. Credits
  11. Harvey Mudd College
    Professor Elizabeth Sweedyk
    Stephen DiVerdi
    Ethan Drucker
    Joshdan Griffin
    Jason Wither
    © 2002

    Table Of Contents