【发布时间】:2013-11-05 05:51:55
【问题描述】:
所以,我正在尝试实现截锥体剔除。这里的问题是,在我这样做之前,我需要了解一些事情。
首先是平面相交:
我的理解是一个平面可以通过3个点来定义;我们就叫他们p0, p1, and p2吧。
鉴于此,我们知道平面的法线可以如下计算:
(伪代码)
vec3 edge0 = p1 - p0;
vec3 edge1 = p2 - p0;
vec3 normal = normalize( cross( edge0, edg1 ) ) // => edge1 X edge2 / length( edge1 X edge2 );
现在,假设我们有一个函数,它基本上告诉我们给定点是否以某种方式“穿过”平面。
(摩尔伪代码)
bool crossesPlane( vec3 plane[3], vec3 point )
{
vec3 normal = getNormal( plane ); // perform same operations as described above
float D = dot( -normal, plane[ 0 ] ); // plane[ 0 ] is arbitrary - could just as well be the 2nd or 3rd point in the array
float dist = dot(normal, point) + D;
return dist >= 0; // dist < 0 means we're on the opposite side of the plane's normal.
}
这背后的逻辑推理是,由于视锥体包含六个单独的平面(近、远、左、上、右、下),我们希望抓住这六个平面中的每一个并基本上“通过”他们到crossesPlane() 函数,针对单个点(一个点,该点的六个测试)。
如果对crossesPlane() 的这六个调用之一返回false,那么我们想要剔除有问题的点,从而有效地导致该点被截锥体剔除,当然该点不会被渲染.
问题
- 这是正确剔除视锥的正确方法吗?
- 如果是这样,获取给定多边形的任意顶点列表,并使用此方法对每个顶点执行此测试,是一种有效的方法吗?
- 虽然 AABB 可用于代替多边形/网格进行剔除测试,但它们是否仍常用于此场景,是否仍被视为“通用”goto 方法?
注意
如果在这方面 D3D 和 OpenGL 之间有任何值得一提的实现差异,我们将不胜感激。
【问题讨论】:
-
通常我们在检查平截头体平面之前进行齐次变换,以便比较是针对 1、-1 等。
-
@MarkPing:适用于测试单个顶点,但不适用于 AABB 或边界球等形状,因为这些形状在同质空间中不再是球形的矩形。因此,AFAIK,在视图空间中进行测试更为常见。
标签: opengl 3d computer-science computational-geometry direct3d