Maximizing Rendering Performance

Scene-Graph Organization

An HSF file is essentially an archive of a HOOPS/3dGS scene-graph. Even if HOOPS/3dGS is not used as the graphics system for rendering, the organization of the scene-graph inside the HSF file can affect rendering performance. Optimal scene-graph structure is covered in the database structure part of the Programming Guide.

Critical areas include keeping segments to a minimum, organizing the scene-graph based on attributes rather than geometry, using ‘shell’ primitives whenever possible to represent tessellated data, and making sure that the shells are as large as possible.

Keep in mind that a scene-graph is meant to serve as an optimal organization of the graphical information, rather than higher-level application information such as ‘assemblies’, ‘parts’, etc… Structuring the scene-graph based on the organization of higher-level application data-structures, while perhaps convenient, can severely compromise rendering performance and memory usage inside the application which is doing the reading. However, the HOOPS/Stream Toolkit’s range of HSF opcode objects and customization facilities makes it easy to associate custom (non scene-graph) data with the scene-graph objects and store them in the HSF file, or store the external to the HSF file (perhaps as XML data).

Shell Organization

When defining your HOOPS/3dGS ‘shell’ primitives, you should follow the recommendations in the performance section of the HOOPS/3dGS Programming Guide.

Additionally, the TK_Shell opcode-handler provides support for defining a shell via tristrips. Drawing shells using tristrips maximizes rendering performance, and exporting shells via tristrips makes them immediately available to the reading application (if tristrips weren’t available, the reading application would either have to regenerate trisrips which takes time, or it would have to render the object using triangles). Therefore, shell objects should be exported via tristrips if they are available. This is done by formatting the face list passed into TK_Shell::SetFaces to contain tristrips, and setting the TKSH_TRISTRIPS bit in the shell’s sub-option variable using TK_Shell::SetSubop. For example:

TK_Shell::SetSubop( TKSH_TRISTRIPS | GetSubop() );

Polygon Handedness

Polygon handedness is a basic vector graphics concept. The specifics are covered in this section, but in general, the existence of a polygon handedness setting for an object enables an application to render that object using backplane culling. This typically results in a significant increase in rendering performance.

If a TK_Shell object is being exported to an HSF and can (or should) have a handedness defined for its faces, it is critical to make sure that the handedness attribute is exported to the HSF file. This is achieved by using the TK_Heuristics object to export the #TKE_Heuristics opcode.

This is important because:

  1. The reading application may not be able to determine what a proper handedness is for the shells.

  2. Even if the reading application can determine a proper handedness setting, the scene may look incorrect if the setting is made in the application and wasn’t made at the time of file export (and hence stored with the shells). This is because the HOOPS/Stream Toolkit will explicitly export compressed normals during the writing phase, and it is possible that these normals won’t be consistent with the handedness setting made in the reading application.

If the handedness attribute is going to be exported for a shell or group of shells, it is important to make sure that all the faces in the shell are all defined with a consistent point ordering. Otherwise some faces will be ‘backwards’, and the object will have holes in it if a viewing application renders the object by relying on the existence of a handedness setting to perform backplane culling.