2

A common way to increase performance of a GPU is to use depth-sorting. You'd want to draw the objects that are closest to you (the camera/viewport) first, that way every fragment(pixel) behind gets disposed early by the Z-Buffer.
In case of transparent objects you want to render them from back to front, to maintain the correct transparency.

I am currently sorting my 3d objects every frame on the CPU, based on distance from the camera/viewport. There are about 9000 of them (could easily be much more or less) so logically it's quite a performance hit on the CPU (sometimes more than just rendering unsorted 3d objects on the GPU). I have just a single list of 3d objects with their position, no fancy space partitioning or anything.

I am rendering my objects using an instance buffer that contains matrix data for each object.

My questions seem simple:

  • How should I sort my 3d objects? On the CPU, or on the GPU? If I should sort them on the GPU, how?
  • How often should I sort my 3d objects? Should I sort them every frame? Should I make a trade-off by sorting them every second frame, or maybe only sorting the objects once per second?

Most of the CPU time seems to be destroyed by sorting the array of distances, rather than calculating the distances themselves...

Some example code (C#):

MatrixDistance[] distances = new MatrixDistance[_transformList.Count];
        Vector3 camPos = cam.GetCameraData().Eye;
        for (int i = 0; i < _transformList.Count; i++)
        {
            Vector3 v;
            v.X = camPos.X - _transformList[i].M14;
            v.Y = camPos.Y - _transformList[i].M24;
            v.Z = camPos.Z - _transformList[i].M34;
            float squaredD = v.X * v.X + v.Y * v.Y + v.Z * v.Z;
            var newMD = new MatrixDistance(_transformList[i], squaredD);
            distances[i] = newMD;
        }
        Array.Sort(distances);
        _distanceSortedTransformList = new List<Matrix>();
        for (int i = 0; i < distances.Length; i++)
        {
            _distanceSortedTransformList.Add(distances[i].Matrix);
        }

Where MatrixDistance is the following class:

class MatrixDistance: IComparable<MatrixDistance>
{
    public Matrix Matrix;
    public float Distance;

    public MatrixDistance(Matrix m, float d)
    {
        Matrix = m;
        Distance = d;
    }

    public int CompareTo(MatrixDistance other)
    {
        return this.Distance.CompareTo(other.Distance);
    }
}
ManIkWeet
  • 1,298
  • 1
  • 15
  • 36
  • Maybe you need to use a sort algorithm that takes less time when the array is already ordered, for example a binary search insertion. – Forestrf May 18 '15 at 01:08
  • Maybe this can help you: http://stackoverflow.com/questions/220044/which-sort-algorithm-works-best-on-mostly-sorted-data – Forestrf May 18 '15 at 01:14
  • I tried alternative sorting algorithms in C#, none of them are faster than the Array.Sort one, sadly. – ManIkWeet May 19 '15 at 14:22

0 Answers0