我正在爲我的計算機科學學士學位項目工作,我很難搞清楚如何做題目所說的事情。 假設攝像機在原點向下看-Z在gl座標(或世界座標中的正z) 此外,我的投影矩陣基於16x9縱橫比和40度垂直fov。 zfar是1000,znear是1.以世界座標計算z_far平面的頂點。
我已經從2個不同的角度來解決這個問題。我試圖通過矩陣數學計算出來,並且還使用了trig。然而,迄今爲止,這兩種方法都無法正常工作。
我的第一本能是取我的投影矩陣,得到矩陣的逆矩陣,然後乘以組成zfar平面的齊次座標。 例如:
vec4(-1.0,1.0,-1.0,1.0) * inverse_projection// calculates top left vertex of z_far plane in world coords etc..
下面是代碼,演示了我的意思。理論上,在將{-1,1,-1}乘以逆投影矩陣後,得到的向量應該具有1000的z座標,因爲這是構造投影矩陣時使用的zfar。
glm::vec4 pp = glm::vec4(-1, 1, -1, 1.0);
printf("zfar[0] = %.2f, %.2f, %.2f, %.2f\n", pp.x, pp.y, pp.z, pp.w);
pp = pp * inverse_projection;
printf("zfar[0] * inverse_projection = %.2f, %.2f, %.2f, w=%.2f\n", pp.x/pp.w ,pp.y/pp.w ,pp.z/pp.w ,pp.w);
pp = pp * projection;
printf("zfar[0] * projection = %.2f, %.2f, %.2f, w=%.2f\n", pp.x/pp.w ,pp.y/pp.w ,pp.z/pp.w ,pp.w);
輸出:
zfar[0] = -1.00, 1.00, -1.00, 1.00
zfar[0] * inverse_projection = -0.21, 0.12, -0.33, w=1.50
zfar[0] * projection = -1.00, 1.00, -1.00, w=1.00
但是,正如你所看到的,它說,在世界座標,z_far爲-0.33,當它應該是在它-1000甚至沒有接近被正確。我的猜測是,我沒有W座標正確的成功翻譯成世界座標。
我也嘗試通過trg計算zfar。
void test_getFrustumInWorld(double height, double width, double v_fov, double z_near, double z_far, glm::mat4 projection)
{
//height and width refer to height and width of screen
glm::vec4 z_far_world[4];
double z_far_height = (tan(v_fov/2)*z_far)*2;
double aspect_ratio = height/width; //how many heights there are in one width
double z_far_width = z_far_height * aspect_ratio;
double zf_right = z_far_width/2.0;
double zf_top = z_far_height/2.0;
z_far_world[0] = glm::vec4(-zf_right, zf_top, 1000.0, 1.0);
z_far_world[1] = glm::vec4(-zf_right,-zf_top, 1000.0, 1.0);
z_far_world[2] = glm::vec4(zf_right,-zf_top, 1000.0, 1.0);
z_far_world[3] = glm::vec4(zf_right, zf_top, 1000.0, 1.0);
for(int i=0; i< 4; i++)
{
double w = z_far_world[i].w;
printf("z_far_world[%d] = {%.2f, %.2f, %.2f, w=%.2f}\n",i,z_far_world[i].x/w, z_far_world[i].y/w, z_far_world[i].z/w, z_far_world[i].w);
}
printf("\nprojected:\n");
for(int i=0; i< 4; i++)
{
z_far_world[i] = z_far_world[i] * projection;
double w = z_far_world[i].w;
printf("z_far_world[%d] = {%.2f, %.2f, %.2f, w=%.2f}\n",i,z_far_world[i].x/w, z_far_world[i].y/w, z_far_world[i].z/w, z_far_world[i].w);
}
}
輸出:
z_far_world[0] = {-1258.40, 2237.16, 1000.00, w=1.00}
z_far_world[1] = {-1258.40, -2237.16, 1000.00, w=1.00}
z_far_world[2] = {1258.40, -2237.16, 1000.00, w=1.00}
z_far_world[3] = {1258.40, 2237.16, 1000.00, w=1.00}
projected:
z_far_world[0] = {0.16, -0.50, 0.50, w=-2002.00}
z_far_world[1] = {0.16, 0.50, 0.50, w=-2002.00}
z_far_world[2] = {-0.16, 0.50, 0.50, w=-2002.00}
z_far_world[3] = {-0.16, -0.50, 0.50, w=-2002.00}
在輸出的該第一塊中的數字,是我到達視圖TRIG計算的座標。 第二個數字塊是應用投影矩陣後的頂點。一旦投影矩陣被應用,結果座標應該是所有1和-1的某種組合。但是像{0.16,0.5,0.5}這樣的東西出現了。這是完全錯誤的。 也只是爲了說明,輸出是由W劃分後的座標。 我到底在想什麼?這應該很簡單,但沒有任何意義。
我哪裏錯了?我誤解了什麼?我完全卡住了。
Aaah耶。我認爲我是錯誤的,或者只是誤解了當我第一次學習opengl座標系時被告知的內容。 我發現,雖然我的主要問題,至少在trig方法中,我的FOV是度數而不是弧度。 – shalnon