Неточная векторная проекция OpenGL - PullRequest
0 голосов
/ 07 февраля 2012

Я создаю перспективную проекцию так:

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

Что я делаю не так?

Ответы [ 2 ]

1 голос
/ 07 февраля 2012

Оказалось, что я нырял глубиной вместо 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 голосов
/ 08 февраля 2012

С другой стороны, вы можете выполнять умножение матриц внутри шейдера.Это намного быстрее, чем в JS.

Вот хорошее начало: http://www.davidcornette.com/glsl/glsl.html

...