The traditional model-based special effects industry have a long tradition of building multiple models of objects to satisfy various shot requirements. Long shots can utilize relatively small and undetailed models while closeups often use very large and detailed models. In computer graphics, we can benefit by adopting a similar methodology, because simpler models require less time and memory to render versus their large and complex versions.
PhotoRealistic RenderMan has implemented Level of Detail. Beneficial features are:
The current detail is the raster space area of the projection of the specified bounding box onto the screen. The current detail range specifies the range of details over which the particular model representation is to be used. The detail range is given by four numbers:
Detail[xmin xmax ymin ymax zmin zmax
Any subsequently defined geometric primitive will be used as follows:
DetailRange[minvisible lowertransition uppertransition maxvisible
The four detail parameters trace out a graph describing the relative importance of each representation of the model. When a particular representation's importance is zero, it is not drawn. Where the importance is one, this representation's primitives (and presumably no others) will be rendered normally. Where the importance lies between zero and one, the current representation will be blended with other representations based upon their relative importance.
AttributeBegin # push the graphics state Detail [-1 1 -2 2 0 8] # setup a "ruler" for detail calcs DetailRange [0 0 1 4] # ... primitives for the low detail model (< 2 pixels) DetailRange [1 4 256 400] # ... primitives for the medium detail model DetailRange [256 400 1e38 1e38] # ... primitives for the high detail model AttributeEnd # pop the graphics state, LOD object done
One may use as few or as many levels as desired, but the sum of all model importances should be 1.0 over the entire range of potential detail values to keep objects from being over or under represented in any particular image. In practice, it may be valuable to underrepresent a low level representation to allow it to fade out as it falls below some minimum size.
Three different models of a chair were created. The simplest is only two bilinear patches. The second has several patches, and some simple cylinders for the spindles in the back. The most detailed model has nicely sculpted surfaces for all of the spindles.
A RIB file was creating specifying appropriate detail levels for each reprentation, and chairs at different distances were rendered. Accross the top, representations were color coded to show how the various representations are smoothly blended. The chairs accross the bottom illustrate a more realistic application. Even when animated, the transitions between these models occur smoothly.
As another example, we create three separate models of a fractal mountain. The largest represents about seventeen megabytes of data, the smallest just over sixty kilobytes. Two movies were generated showing transitions between levels. The first movie shows color coding to illustrate the smooth shifting between levels. The second movie uses a normal matte shader for all three representations.
One point glossed over so far is memory usage. Since both models need to be specified in the RIB file, a great deal of memory is tied up in detailed objects which are potentially never visible.
When used in combination with new procedural primitive functions, the detailed object
descriptions need never be loaded if they aren't used. As an example,
suppose we have three versions of a particular object, stored in three rib files named
represent the underlying object at various levels of detail.
AttributeBegin # push the graphics state Detail [-1 1 -1 1 -1 1] # setup a "ruler" for detail calcs DetailRange [0 0 1 4] # Procedural "DelayedReadArchive" [ "small.rib" ] [-1 1 -1 1 -1 1] DetailRange [1 4 256 400] # Procedural "DelayedReadArchive" [ "medium.rib" ] [-1 1 -1 1 -1 1] DetailRange [256 400 1e38 138] # Procedural "DelayedReadArchive" [ "big.rib" ] [-1 1 -1 1 -1 1] AttributeEnd
Procedural "DelayedReadArchive" geometric primitive acts as a
placeholder. The corresponding rib file is only read when the bounding box given
is determined to be potentially visible. If the box is determined to be outside
the current detail range (or otherwise invisible), it will never be read at all.
This means that you can create RIB files which include large amounts of geometry
without knowing for sure what level of detail they will be drawn.
Procedural objects can also call programs to generate RIB streams for additional flexibility. Consult the Using Procedural Primitives application note for more information.
Level of detail only helps in rendering images using models at several levels of detail. It does not help at all with the actual creation of these models. The smoothness of transitions is largely dependant on how carefully the models are constructed. If silhouettes change radically, or surface coloration changes drastically, it may be possible to see the changes, even if they occur smoothly.
Pixar Animation Studios