土圭垚㙓數學課(二)視錐體八個頂點的計算方法

視錐體是攝像機可見的空間,看上去像截掉頂部的金字塔。視錐體由6個裁剪面圍成,構成視錐體的4個側面稱爲上左下右面,分別對應屏幕的四個邊界。爲了防止物體離攝像機過近,設置近切面,同時爲了防止物體離攝像機太遠而不可見,設置遠切面。本文將介紹一下視錐體八個頂點的計算方法。


我們就以Unity3D(5.6.0f3)爲例。

首先取fov(fieldOfView),即攝像機在豎直方向上的張角。

float fov = Camera.main.fieldOfView;
還有aspect,也就是屏幕的寬高比。

float asp = Camera.main.aspect;

然後計算獲得一個yf參數,用來表示視錐體的上下側面與xz平面的偏移量。

float yf = Mathf.Tan(fov/2 * Mathf.Deg2Rad);

爲什麼要除以2?因爲我們知道fov是攝像機在豎直方向上的張角,也就是說以xz平面爲中心,上下各有fov/2的角度。

然後計算一下xf參數,同理,用來表示視錐體的左右側面與yz平面的偏移量。

float xf = yf * asp;

然後是視錐體四個側邊(也就是不在近平面或原平面上的邊)的方向向量。

Vector3 f0 = Camera.main.transform.forward - Camera.main.transform.right * xf - Camera.main.transform.up * yf;
Vector3 f1 = Camera.main.transform.forward - Camera.main.transform.right * xf + Camera.main.transform.up * yf;
Vector3 f2 = Camera.main.transform.forward + Camera.main.transform.right * xf - Camera.main.transform.up * yf;
Vector3 f3 = Camera.main.transform.forward + Camera.main.transform.right * xf + Camera.main.transform.up * yf;

(他們不是單位向量哦!)

之所以列出這四個向量,是因爲他們有時候會特別有用,比如說計算視錐體與一個平面的相交多邊形。

需要注意的是這裏計算的是世界空間的向量,所以要使用Camera的forward,right和up來計算。既然這麼說了,你一定想到了另外一種寫法。

Matrix4x4 l2w = Camera.main.transform.localToWorldMatrix;
Vector3 f0 = l2w * new Vector3(-xf,-yf,1);
Vector3 f1 = l2w * new Vector3(-xf, yf,1);
Vector3 f2 = l2w * new Vector3( xf,-yf,1);
Vector3 f3 = l2w * new Vector3( xf, yf,1);

最後計算出八個頂點:

float fcp = Camera.main.farClipPlane;
float ncp = Camera.main.nearClipPlane;
Vector3 cpt = Camera.main.transform.position;
Vector3 farLeftBottom = cpt + fcp * f0;
Vector3 farLeftTop = cpt + fcp * f1;
Vector3 farRightBotoom = cpt + fcp*f2;
Vector3 farRightTop = cpt + fcp * f3;
Vector3 nearLeftBottom = cpt + ncp * f0;
Vector3 nearLeftTop = cpt + ncp * f1;
Vector3 nearRightBotoom = cpt + ncp*f2;
Vector3 nearRightTop = cpt + ncp * f3;

額~完整代碼自己拼好嗎?親們?

發佈了157 篇原創文章 · 獲贊 340 · 訪問量 59萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章