這次來討論一下視景體剔除的一些技巧,視景體在3d程式中是個很重要的概念,我們可以把視景體看作是一台攝像機也就是肉眼能夠看到的空間.視景體以外的東西是看不到的,可以利用這點來剔除多餘的模型,於是不必要的頂點將不會進入管線,這能夠提高不少fps.
首先來看一下視景體是個啥東西
就是這麼個六面稜錐,這是經過檢視變換的樣子,那麼接下來應該進行投影變換,那麼視景體就會變成這樣
是乙個立方體,範圍是-1到1.(ndc座標系)
假設空間中一點p(x,y,z,1)經過這一系列變換變成p1(x1/w1,y1/w1,z1/w1,1) 並且假設projectmatrix左乘modelviewmatrix得到的第一行是(a,b,c,d),那麼有
a*x+b*y+c*z+d=x1
假設變換矩陣的最後一行(e,f,g,h),那麼有
e*x+f*y+g*z+h=w1
因為p1在ndc座標系,範圍是-1到1,那麼在視景體左面上的點都符合x1/w1=-1,式子可以變為x1+w1=0
代入之前的等式:
a*x+b*y+c*z+d+e*x+f*y+g*z+h=0
於是得到:
(a+e)*x+(b+f)*y+(c+g)*z+(d+h)=0
一般的平面方程是:
a*x+b*y+c*z+d=0 (a,b,c)是平面的法向量
於是左側平面的方程就是
(a+e)*x+(b+f)*y+(c+g)*z+(d+h)=0 其中的x,y,z就是空間中的點座標
那麼對應的**就是:
mfrustum[1][0] = clip[ 3] + clip[ 0];
mfrustum[1][1] = clip[ 7] + clip[ 4];
mfrustum[1][2] = clip[11] + clip[ 8];
mfrustum[1][3] = clip[15] + clip[12];
其中的clip就是變換矩陣modelviewprojectmatrix
clips=projs*modls;
然後對平面方程進行發現歸一化,這對於求點到面的距離有好處:
t = glfloat(sqrt( mfrustum[0][0] * mfrustum[0][0] + mfrustum[0][1] * mfrustum[0][1] + mfrustum[0][2] * mfrustum[0][2] ));
mfrustum[0][0] /= t;
mfrustum[0][1] /= t;
mfrustum[0][2] /= t;
mfrustum[0][3] /= t;
其它5個面也這樣推導,最終的**是這樣的:
glfloat mfrustum[6][4];
void updatefrustum()
然後判斷球體在視景體內部還是外部,根據點到平面的距離公式計算
d=a*x+b*y+c*z-(a*xp+b*yp+c*zp) (xp,yp,zp)是面上的點,且平面方程是經過法線規範化處理的.
a*xp+b*yp+c*zp=-d
那麼公式變為
d=a*x+b*y+c*z+d
d是有正負的,正距離是與法向量同向,負距離與法向量反向.
那麼判斷是否在視景體內部的**如下:
bool sphereinfrustum(float x,float y,float z,float radius)
return true;
}
在每一幀都呼叫updatefrustum()就能夠更新視景體平面,然後把模型的中心,大致半徑作為變數呼叫sphereinfrustum即可判斷模型是否能夠看得見.
趕緊構造視景體,盡情地剔除看不見的東西吧!
參考:
由攝像機的內參K計算視景體
由攝像機的內參k計算視景體 glfrustum的引數推導 風之憂傷 建立視景體的glfrustum函式的形式為 glfrustum left,right,bottom,top,near,far 前4個引數表示座標,可正可負,後兩個引數表示距離,為正數.大多數opengl的參考文獻都只是簡單的介紹了一...
心跳監測與服務剔除
服務剔除 小結假如志玲姐姐親了你一口,你卻沒有心動的感覺,那麼一定是你停止了心跳 今天社保中心來了一位釘子戶,90多歲的王大爺又興高采烈的來給自己快120歲的老父親領社保了!工作人員這一想,好像 不對啊,這老父親120歲的年紀都可以上健力士世界紀錄了,要不咱幫老爺子去申請一下?王大爺一聽可慌了,連連...
代數方程與差分方程模型
代數方程與差分方程模型 原創tianguiyuyu 發布於2018 05 29 23 13 18 閱讀數 1149 收藏 展開1 代數方程模型。所謂的代數方程模型就是有一邊變數表示未知量,代數方程,即由多項式組成的方程。有時也泛指由未知數的代數式所組成的方程,包括整式方程 分式方程和根式方程。例如 ...