C/C++中三维平面的优选表示

Preferred Representation of a 3D-Plane in C/C++

本文关键字:表示 平面 三维 C++      更新时间:2023-10-16

当C/C++是首选语言时,在3D图形中表示固定维平面(结构)的首选方式是什么。

我们应该吗

  1. 将归一化的平面法向量和原始距离存储为单独的实体,或者我们应该
  2. 将它们一起表示为非归一化向量

第一种替代方案需要一个额外的浮点/双精度,但另一方面,在对法线进行操作的算法中效率更高,因为它已经被预先计算过了。如果我们分别改变法线和偏移,第一种选择在数值上也更稳定。

遗憾的是,C++不是处理平面的最佳语言。首先,我们可以认为使用四个浮点值是一个不错的选择,因为它适合SSE和VMX中的SIMD寄存器。因此,我们可能有一个只有128位成员的类,前三个值表示平面法线,最后一个值表示距离(就像齐次坐标一样,如果我们只关心距离测试的符号,平面并不总是需要归一化法线)。

但是,当我们使用平面对点、球体和其他体积进行分类时,实现单个平面到点的距离函数将导致次优算法,因为大多数时候,我们知道我们将针对少量平面测试大量点。还有优化的空间!

这里的问题有一个名字,事实上,不是问题,而是我们表示信息的方式。它是结构阵列与阵列结构(AOS与SOA)。

在3D引擎中,一个常见的练习是边界体积截头体剔除!通常的截头体由6个平面组成,正确的表示不是具有std::array<Plane,6>成员的frustum类,但最有可能的是,8个SIMD寄存器的布局为:{ P0X, P1X, P2X, P3X }, { P4X, P5X, FREEPLANE1X, FREEPLANE2X }, ...,依此类推,用于Y、Z和D。不是C++,但用于SIMD编程要好得多。

更喜欢SOA对点的重新补偿也可能是有用的。

结论:最好的表示取决于什么算法和什么样的数据集会进入你的平面。