2012-02-06 108 views
0

我創建透視投影是這樣的:OpenGL的矢量投影不精確

function quickViewMatrix(pos, center, w, h) 
{ 
    var modelview = mat4.create(); 
    mat4.lookAt(pos, center, [ 0, 0, 1 ], modelview); 
    var projection = mat4.create(); 
    mat4.perspective(45, w/h, 1, 20, projection); 
    var viewTransformation = mat4.create(); 
    mat4.multiply(projection, modelview, viewTransformation); 
    return viewTransformation; 
} 

所以,viewTransformation = P M.該矩陣然後被傳遞到頂點着色器,其中乘法(P M)* V完成了。

現在我想手動將世界座標轉換爲屏幕座標。我這樣做:

function worldToScreen(x, y, z, w, h) 
{ 
    var out = vec3.create(); 
    mat4.multiplyVec3(cameraTransform, [ x, y, z ], out); 
    out[0] /= out[2]; 
    out[1] /= out[2]; 
    out[0] = (out[0] + 1.0)/2.0 * w; 
    out[1] = (1.0 - out[1])/2.0 * h; 
    return { x: out[0], y: out[1] }; 
} 

cameraTransform這裏是使用上面的函數創建的矩陣。這似乎適用於屏幕的上部區域,但是我得到的更低(更接近相機!),它變得越不準確。

我改變一個平面屏幕的所有點的座標手動這種方式(顯示爲紅色),並結束了與此:

http://puu.sh/fXGB

我在做什麼錯?

回答

1

原來我是深度而不是w,這導致了問題。

我的新功能:

function worldToScreen(x, y, z, w, h) 
{ 
    var out = []; 
    mat4.multiplyVec4(cameraTransform, [ x, y, z, 1.0 ], out); 
    out[0] /= out[3]; 
    out[1] /= out[3]; 
    out[2] /= out[3]; 
    out[0] = (out[0] + 1.0)/2.0 * w; 
    out[1] = (1.0 - out[1])/2.0 * h; 
    return { x: out[0], y: out[1]}; 
} 
0

在一個側面說明,你可以從着色器內執行矩陣乘法。這比在JS中做這個要快得多。

這裏有一個良好的開端: http://www.davidcornette.com/glsl/glsl.html

+0

我打算這樣做,但我不得不先找到正確的方法。 Javascript比GLSL更容易調試。 – Overv 2012-02-25 15:02:59