獲取View Frustum的6個平面

在3D圖形學中,一種優化的手法,叫做物體剔除(Object Culling)。這種技術的提出是基於這樣的策略:我們不希望將不存在View Frustum裏面的物體送往流水線中進行處理。雖然,你可能會說,現在的圖形卡都已近支持了三角形剔除的技術。但是,不要忘了流水線的步驟。我們是先進行Vertex Processing,然後才進行Geometry Processing。而圖形卡對三角形的剔除是在Geometry Processing這個階段進行的。也就是說,即使能夠剔除它們,我們依然要在Vertex Processing中對這些將來需要丟棄的頂點進行Vertex Processing處理。而我們知道,Vertex Processing這個階段往往會進行座標變換,光照計算等等費時的操作。所以,如果能夠在Vertex Processing之前,也就是在Application階段,在我們的CPU中將這些根本不需要處理的物體剔除的話,會大大的提高程序的效率。而想要將物體剔除,我們就需要知道這個物體是否在View Frustum中。而爲了判斷這個條件,我們就需要確定構成View Frustum的6個平面的方程。所以,本篇文章,就向大家講述,如何獲取View Frustum的6個平面方程。

 

void Frustum::createPlane(const Camera* camera)

{

    const Mat4& mat = camera->getViewProjectionMatrix();  //獲得視圖投影矩陣

    //ref http://www.lighthouse3d.com/tutorials/view-frustum-culling/clip-space-approach-extracting-the-planes/

    //extract frustum plane

    //  (X x a11 + Y x a12 + Z x a13 + a14) + (X x a41 + Y x a42 + Z x a43 + a44) > 0

    //  X(a11 + a41) + Y(a12 + a42) + Z(a13 + a43) + a14 + a44 > 0

    // 負數大概是因爲 p.n = d p就是(x,y,z),n就是(a11 + a41,a12 + a42,a13 + a43) d如果不變的話,n就應該取負數

    _plane[0].initPlane(-Vec3(mat.m[3] + mat.m[0], mat.m[7] + mat.m[4], mat.m[11] + mat.m[8]), (mat.m[15] + mat.m[12]));//left

    _plane[1].initPlane(-Vec3(mat.m[3] - mat.m[0], mat.m[7] - mat.m[4], mat.m[11] - mat.m[8]), (mat.m[15] - mat.m[12]));//right

    _plane[2].initPlane(-Vec3(mat.m[3] + mat.m[1], mat.m[7] + mat.m[5], mat.m[11] + mat.m[9]), (mat.m[15] + mat.m[13]));//bottom

    _plane[3].initPlane(-Vec3(mat.m[3] - mat.m[1], mat.m[7] - mat.m[5], mat.m[11] - mat.m[9]), (mat.m[15] - mat.m[13]));//top

    _plane[4].initPlane(-Vec3(mat.m[3] + mat.m[2], mat.m[7] + mat.m[6], mat.m[11] + mat.m[10]), (mat.m[15] + mat.m[14]));//near

    _plane[5].initPlane(-Vec3(mat.m[3] - mat.m[2], mat.m[7] - mat.m[6], mat.m[11] - mat.m[10]), (mat.m[15] - mat.m[14]));//far

}

 

 

 

 

 

 

 

Clip Space Approach – Extracting the Planes

  

In here another approach to extract the view frustum planes is presented based on the properties of clip space.

Consider a point p =(x,y,z,1) on the 3D world. Consider also a modelview matrix Mand a projection matrix P. The point p is transformed by matrices M and P as point pc =(xc,yc,zc,wc) in clip space using:

The point pc is in homogeneous coordinates, and when normalised becomes pcn:

In normalised clip space the view frustum is an axis aligned box centered in the origin, and bounded by the following planes:

  • Left Plane: x’ = -1
  • Right Plane: x’ = 1
  • Top Plane: y’ = 1
  • Bottom Plane: y’ = -1
  • Near Plane: z’ = -1
  • Far Plane: z’ = 1

This implies that the point pcn =(x’,y’,z’) is inside the view frustum if:

Then the point pc, in non-normalized coordinates, must obbey the following conditions in order to be inside the view frustum:

Based on this information it is possible to extract the six planes, in world coordinates, that bound the view frustum. The point pc is on the “right” side of the left plane if

Consider p and A=MP as described below

Then xc and wc can be defined as a function of p = (x,y,z,w), and A.

Therefore the following inequation must be true if p is on the right side of the left plane.

A little algebraic manipulation gives

So the left plane (Ax+By+Cz+D=0) is defined as:

where col1 and col4 are the first and forth columns of matrix A, respectively.

If the only objective is to find out if a point is inside or outside of the frustum then the plane as defined is ok. However when testing spheres, which require computing the distance from the center of the sphere to the plane, it is advisable to normalize the plane.

The right plane can be obtained in a similar manner:

The following coefficients are obtained for the right plane:

The remaining planes are obtained as follows:

Bottom Plane

Top Plane

Near Plane

Far Plane

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章