Я создаю перспективную проекцию так:
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
Что я делаю не так?