提取视图Frustum平面(Hartmann& Gribbs方法)

时间:2012-10-11 09:59:59

标签: math 3d frustum culling occlusion-culling

我一直在努力解决the Hartmann/Gribbs method of extracting the Frustum planes一段时间,但收效甚微。我想构建一个摄像机视图 - 视锥体来剔除我的场景。

我正在使用右手坐标系中的柱主矩阵。 (OpenGL风格 - 我使用的是C#和Playstation Mobile,但数学应该是相同的)

我想让我的飞机进入World-Space,所以我从View-Projection Matrix(即projectionMatrix * viewMatrix)构建了我的平截头体。视图矩阵与相机的世界变换相反。

问题是;不管我调整什么,我似乎无法得到正确的截头。我想我可能会遗漏一些明显的东西。

如果我在俯视z轴时向左或向右“拉”我的相机,我的飞机的法线会发生变化,以至于它们总是指向场景的原点 - 这让我觉得它们不在世界空间...

2 个答案:

答案 0 :(得分:4)

投影矩阵中的平面可以使用hartmann / gribbs方法提取,如下所示(专栏文):

void extract_planes_from_projmat(
        const float mat[4][4],
        float left[4], float right[4], float top[4], float bottom[4],
        float near[4], float far[4])
{   
    for (int i = 4; i--; ) left[i]      = mat[i][3] + mat[i][0];
    for (int i = 4; i--; ) right[i]     = mat[i][3] - mat[i][0]; 
    for (int i = 4; i--; ) bottom[i]    = mat[i][3] + mat[i][1];
    for (int i = 4; i--; ) top[i]       = mat[i][3] - mat[i][1];
    for (int i = 4; i--; ) near[i]      = mat[i][3] + mat[i][2];
    for (int i = 4; i--; ) far[i]       = mat[i][3] - mat[i][2];
}

请参阅:

注意:如果矩阵组件未经规范化并且您需要 Hessian Normal Form 平面,则需要对生成的平面进行标准化。

答案 1 :(得分:0)

缺少的部分:

comboMatrix = projection_matrix * Matrix4_Transpose(modelview_matrix)

然后,OpenGL的世界空间视锥面提取完全与 Hartmann / Gribbs方法中所述:

p_planes[0].a = comboMatrix._41 + comboMatrix._11;
p_planes[0].b = comboMatrix._42 + comboMatrix._12;
p_planes[0].c = comboMatrix._43 + comboMatrix._13;
p_planes[0].d = comboMatrix._44 + comboMatrix._14;
// Right clipping plane
p_planes[1].a = comboMatrix._41 - comboMatrix._11;
p_planes[1].b = comboMatrix._42 - comboMatrix._12;
p_planes[1].c = comboMatrix._43 - comboMatrix._13;
p_planes[1].d = comboMatrix._44 - comboMatrix._14;
// Top clipping plane
p_planes[2].a = comboMatrix._41 - comboMatrix._21;
p_planes[2].b = comboMatrix._42 - comboMatrix._22;
p_planes[2].c = comboMatrix._43 - comboMatrix._23;
p_planes[2].d = comboMatrix._44 - comboMatrix._24;
// Bottom clipping plane
p_planes[3].a = comboMatrix._41 + comboMatrix._21;
p_planes[3].b = comboMatrix._42 + comboMatrix._22;
p_planes[3].c = comboMatrix._43 + comboMatrix._23;
p_planes[3].d = comboMatrix._44 + comboMatrix._24;
// Near clipping plane
p_planes[4].a = comboMatrix._41 + comboMatrix._31;
p_planes[4].b = comboMatrix._42 + comboMatrix._32;
p_planes[4].c = comboMatrix._43 + comboMatrix._33;
p_planes[4].d = comboMatrix._44 + comboMatrix._34;
// Far clipping plane
p_planes[5].a = comboMatrix._41 - comboMatrix._31;
p_planes[5].b = comboMatrix._42 - comboMatrix._32;
p_planes[5].c = comboMatrix._43 - comboMatrix._33;
p_planes[5].d = comboMatrix._44 - comboMatrix._34;

这些飞机现在位于世界空间中,可用于平截锥体剔除世界空间对象。

for(int i = 0; i < 6; i++)
{
    var dist = dot3(world_space_point.xyz, p_planes[i].xyz) + p_planes[i].d + sphere_radius;
    if(dist < 0) return false; // sphere culled
}