提高 GPU 性能的常用方法是使用深度排序。您首先要绘制离您最近的对象(相机/视口),这样后面的每个片段(像素)都会被 Z-Buffer 提前处理。
如果是透明对象,您希望从后到前渲染它们,以保持正确的透明度。
我目前正在根据与相机/视口的距离对 CPU 上的每一帧 3d 对象进行排序。其中大约有 9000 个(可能很容易或多或少),因此从逻辑上讲,它对 CPU 的性能影响很大(有时不仅仅是在 GPU 上渲染未排序的 3d 对象)。我只有一个 3d 对象列表及其位置,没有花哨的空间分区或任何东西。
我正在使用包含每个对象的矩阵数据的实例缓冲区来渲染我的对象。
我的问题似乎很简单:
- 我应该如何分类我的 3d 对象?在 CPU 上,还是在 GPU 上?如果我应该在 GPU 上对它们进行排序,该怎么做?
- 我应该多久对我的 3d 对象进行一次排序?我应该每帧对它们进行排序吗?我应该通过每隔一帧对它们进行排序来进行权衡,还是每秒只对对象进行一次排序?
大多数 CPU 时间似乎都被距离数组排序所破坏,而不是自己计算距离......
一些示例代码(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);
}
其中 MatrixDistance 是以下类:
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);
}
}