我正在创建这样的透视投影:
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这里是使用上述函数创建的矩阵。这似乎适用于屏幕的上部区域,但是我得到的更低(更接近相机!),它变得越不准确。
我用这种方式手动将一个平面的所有点转换为屏幕坐标(以红色显示)并最终得到:
我做错了什么?
答案 0 :(得分: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]};
}
答案 1 :(得分:0)
在旁注中,您可以在着色器中执行矩阵乘法。这比在JS中做得快得多。