|
We define "optimal rendering"
as the optimization of visual integrity with performance.
As such, some of the following suggestions address rendering
speed and architectural basics, while others address the
output of a good picture.
These simple rules apply in all
cases to display rendering. Other output devices (PostScript,
HPGL2, Images, etc.) may require different techniques.
STEP I. Buy a decent graphics
card
In many cases the difference
between a disappointing graphics card and a superb graphics
card can be around $50.00.
STEP II. Use OpenGL whenever
possible
Most graphics cards that cost
more than $100.00 will include a dedicated amount of on-board
rendering memory. So-called "hardware acceleration" works
in tandem with the card's specialized driver to greatly
speed up the performance of OGL-based applications. Other
graphics systems supported by HOOPS/3dGS, such as GDI and
X11, are not capable of using hardware memory. Therefore
it is always recommended that developers use the HOOPS OpenGL
driver as the default display driver. Please read the HOOPS/3dGS
Platform and Device Guide in the documentation section for
detailed OGL driver options.
STEP III. Organize your scene
graph by attribute rather than geometry
In short, organizing a scene
graph by geometric similarity can bring an application to
its knees. There are certainly many cases when localized
geometric organization is desireable, but as a rule the
scene graph architecture should be constructed around the
principle of nodes sharing attributes, such as color. Attribute-level
organization keeps the number of segments relatively low.
STEP IV. Keep segments and
segment operations to a minimum
A greater number of segments
translates to longer database traversal times, more memory
usage, and therefore to slower display updates. In addition,
the expense of costly node-level operations (such as database
searches) is increased by uncontrolled segment populations.
STEP V. Use meshes rather
than shells
If your data allows it, surfaces
should be represented by a HOOPS mesh rather than a shell.
All low-level graphics languages, such as GDI and OGL, draw
surfaces as strips of triangles that are one triangle wide
and have no length limit. These are commonly known as "tristrips",
and fewer tristrips means faster rendering.
HOOPS/3dGS builds tristrips
from surface data before piping them to an output driver,
and as such it must make decisions on the tristrip length.
A mesh will always have the longest tristrips because HOOPS
has a priori information on the dimensions of the
surface (a mesh is always M by N). Therefore a mesh will
also have the fewest tristrips and will render most efficiently.
However HOOPS has no information about the data in a shell,
other than the point connectivity, an therefore the tristrip
count can be much greater.
STEP VI. When using HOOPS
shells, order the faces consistently
To construct the face of a shell
(or any polygon), a series of points are connected in either
a right-handed or left-handed sense. By definition, if you
wrap the fingers of the right hand along the vertices of
a polygon, with the wrist at the first vertex and your fingertips
at the last, then extend your thumb, your thumb is extending
out of the front face of the polygon and the polygon sense
is "right-handed". Likewise, the same polygon with a left-handed
sense will have the same ordering of points but the front
face of the polygon will be on the opposite side.
Polygon handedness and front-face
direction becomes critical when trying to shade surfaces,
and in applying some rendering optimizations such as "backplane
culling". When handedness is not consistent, shading algorithms
produce bad results and this forces HOOPS to compensate.
The extra work of searching for and flipping the orientation
of inconsistent faces can slow rendering by up to thirty
percent. The optimal setting for any model is to have polygon
handedness set to either "right" or "left" and the "bacplane
culling" heuristic set to "on".
STEP VII. Consolidate surfaces
When using shells and meshes,
it is often useful to combine surfaces that share edges.
For shells this avoids some
memory overhead, but more importantly it ensures that Level
Of Detail (LOD) calculations will create geometrically simplified
models that closely approximate the original form. LOD's
for adjacent shells that are not combined may contract and
pull apart from each other, causing cracks and gaps in the
simplified representation of the model. The same LOD considerations
apply to meshes.
There are different ways to
combine surface primitives. The simplest method is to concatenate
the point lists and face lists of two separate surfaces,
and then eradicate the duplicated data with a call to HC_Compute_Optimized_Shell().
However, it is possible but slightly more difficult to "sew"
faces together along seams that do not share points. HOOPS/3dGS
provides some tolerance-setting heuristics for this purpose,
which allow Compute_Optimized_Shell to collapse points within
a certain distance. Depending on the application (engineering
vs. visualization) and the type of model, these heuristics
may or may not be useful.
STEP VIII. Apply light interpolation
wisely
Light interpolation, or "3-d
shading", can be applied to HOOPS surfaces to give visual
dimension to tesselated surfaces. When applying light interpolation
to a model, be sure to shade only those sub-parts of the
surface that are important. Surfaces (shells and meshes)
consist of faces, edges, and vertices. In most cases, optimizing
the shading of a scene involves turning light interpolation
OFF for edges and vertices, but leaving it on for faces.
STEP IX. Generate a maximum
of three Levels Of Detail (LOD's)
The HOOPS LOD capability allows
the developer to specify the degree (ratio) of simplification
between levels of detail. Take for example a shell with
100,000 triangles and three LOD's, with a ratio of 0.5 (50%).
In this case, LOD1 will have 50,000 triangles; LOD2 will
have 25,000 triangles; and LOD3 12,500 triangles.
Our benchmarks show that increasing
the number of LOD's does not significantly improve the performance
of large models during camera transformations. Our standard
suggestion is that the developer create 2 LOD's per model
with a non-static ratio of 10% and 30%. For our shell example,
this strategy would result in LOD1 with 90,000 triangles,
and LOD2 with 60,000.
STEP X. Use Include_Segment
and Insert_Shell_By_Reference whenever possible
The HOOPS function HC_Include_Segment
allows nodes to link with the geometry and attributes of
other nodes without making extra copies of data. The technique
of using Included segments wherever possible saves large
abounts of memory and should be used wherever possible.
Shells are the most commonly
used HOOPS primitive and also the most expensive to render
and store. HOOPS/3dGS provides a special function, HC_Insert_Shell_By_Reference,
which allows the original point and connectivity data to
be kept in the user's own data structures. This allows shell
data to be reused over and over without increasing memory
overhead. Although somewhat similar to using Include segments,
the reference technique does not require HOOPS to have any
copies of the original data, while at least one copy of
the data (and an extra segment) must be present for a shell
to be included into another.
|