2012-02-06 105 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