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