Click or drag to resize

Batching

For raw rendering speed, use the least amount of primitives to represent as many objects as possible.

Triangle Mesh

Combine TriangleMeshPrimitive objects that have the same color. When using indexed triangle lists as input, the triangles do not need to be adjacent. See the Triangle Mesh Primitive topic to learn about indexed triangle lists.

To illustrate combining triangle mesh primitives that share the same color, the following image shows the result of rendering 5 degree extents across the entire globe using 2,592 triangle mesh primitives:

Batching 5 Degree Extents

121.38 fps is reasonable performance; however if we can decrease the number of primitives, we can improve performance even though the number of pixels rendered remains the same. By reducing the number of primitives from 2,592 to 72, the frame rate increases to 994.48:

Batching 30 Degree Extents

This batching relies on primitives sharing the same color so it is limited by the number of unique colors used - 72 in this case. The following class can be used to combine triangle mesh primitives:

C#
public class TriangleMeshBatch
{
    public TriangleMeshBatch(Color color)
    {
        m_color = color;
        m_positions = new List<Cartesian>();
        m_normals = new List<Cartesian>();
        m_indices = new List<int>();
    }

    /// <summary>
    /// Call this one or more times to add triangles to the mesh.
    /// </summary>
    public void Append(TriangulatorResult triangles)
    {
        m_positions.AddRange(triangles.Positions);
        m_normals.AddRange(triangles.Normals);
        m_indices.AddRange(triangles.Indices);
    }

    /// <summary>
    /// Call this once after all calls to Append().
    /// </summary>
    public TriangleMeshPrimitive Commit(CentralBody centralBody, PrimitiveManager primitives)
    {
        TriangleMeshPrimitive mesh = new TriangleMeshPrimitive(SetHint.Infrequent);
        mesh.Set(m_positions, m_normals, m_indices);
        mesh.ReferenceFrame = centralBody.FixedFrame;

        mesh.Color = Color.FromArgb(m_color.R, m_color.G, m_color.B);
        mesh.Translucency = 0.0f;
        primitives.Add(mesh);
        return mesh;
    }

    private readonly Color m_color;
    private readonly List<Cartesian> m_positions;
    private readonly List<Cartesian> m_normals;
    private readonly List<int> m_indices;
}

To use this class, first create an instance, specifying the color of the mesh. Then call Append one or more times to add triangles to the mesh. The triangulator objects do not need to be adjacent to each other. Finally, call Commit to create the primitive. The following code sample combines two extents:

C#
EarthCentralBody earth = CentralBodiesFacet.GetFromContext().Earth;

CartographicExtent extent1 = new CartographicExtent(0, 0, Trig.DegreesToRadians(1), Trig.DegreesToRadians(1));
SurfaceTriangulatorResult result1 = SurfaceExtentTriangulator.Compute(earth, extent1);

CartographicExtent extent2 = new CartographicExtent(Trig.DegreesToRadians(2), 0, Trig.DegreesToRadians(3), Trig.DegreesToRadians(1));
SurfaceTriangulatorResult result2 = SurfaceExtentTriangulator.Compute(earth, extent2);

TriangleMeshBatch batch = new TriangleMeshBatch(Color.Green);
batch.Append(result1);
batch.Append(result2);
TriangleMeshPrimitive mesh = batch.Commit(earth, SceneManager.Primitives);
Point Batch

Instead of creating several PointBatchPrimitive objects, each with a single point, create one PointBatchPrimitive with many points.

For best performance, use large point batches. If a point batch is created for each point in the STK Area Targets for the United States, 13,691 primitives are created. The frame rate is 46.84 fps, as shown below:

One Batch Per Point

Instead, if one point batch is created for each area target, only 134 primitives are created and the frame rate jumps to 1,559.88 fps:

One Batch Per State

The frame rate can be improved to 1,886.59 fps if only one point batch is used to represent every point:

One Batch

In order to combine point batches, it may be necessary to use Set methods with arguments for colors if the original point batches have different colors. These methods allow each point in a point batch to have a unique color.

Text Batch

Use one TextBatchPrimitive object to render several strings. However, in many cases, rendering thousands of strings with a small number of objects will be as efficient as rendering with just one, and is likely to provide better culling.

To demonstrate TextBatchPrimitive performance, the following image shows the result of rendering a string for each point in the STK Area Targets for the United States. 13,691 strings, with a total of 192,073 characters, are rendered.

One Batch Per String

The strings were rendered using a various number of text batches, as shown in the table. Peak performance is achieved when the number of strings (or more precisely characters) in each batch is large. Rendering with 1-1,000 batches yields the best frame rate, rendering with a single batch per string yields a poor frame rate.

Number of text batches

fps

1-1,000

164

1,500

137

2,000

101

5,000

38

13,691 (one batch per string)

14

Since 1,000 batches performed as well as 1 batch, it is recommended to use 1,000 batches to achieve the best view-dependent performance. See the Object Culling topic for the reason why. Keep in mind that you might want to scale the number of batches back when other primitives are in the scene.

Text batches provide a great degree of flexibility to allow grouping several strings into one batch. Using TextBatchPrimitiveOptionalParameters, each string can have a unique color, horizontal origin, vertical origin, pixel offset, and eye offset. The main constraint is each string in a batch must share the same GraphicsFont.

Polyline

Instead of creating several PolylinePrimitive objects with two positions each, create one PolylinePrimitive with several positions. Also, instead of creating several PolylinePrimitive objects, using PolylineType.LineStrip, create one PolylinePrimitive using PolylineType.Lines. This trades memory for better batching.

It is straightforward and beneficial to combine several polylines that use PolylineType.Lines into one polyline. It is also possible to combine several polylines that use PolylineType.LineStrip into a single primitive that uses PolylineType.Lines by duplicating positions. To illustrate this, the following image shows the result of rendering the boundary for each state using a separate primitive at 1,508.04 fps:

Multiple Polylines

If per-position color is used and the type is changed from line strips to individual lines, one polyline primitive can render the boundary for every state and improve the frame rate to 1,915.39 fps:

One Polyline

This uses significantly more memory, more than double the previous method. Be cautious with this technique because it may hurt performance when limited GPU memory is available. If too much memory is used, it will not all fit into GPU memory and will cause more bus traffic.