如何构建透视投影矩阵(无 API) [英] How to build perspective projection matrix (no API)

查看:27
本文介绍了如何构建透视投影矩阵(无 API)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发了一个简单的 3D 引擎(不使用任何 API),成功地将我的场景转换到世界和视图空间,但在使用透视投影矩阵(OpenGL 样式)投影我的场景(从视图空间)时遇到了麻烦.我不确定 fov、near 和 far 值,而且我得到的场景是扭曲的.我希望如果有人可以指导我如何使用示例代码正确构建和使用透视投影矩阵.在此先感谢您的帮助.

I develop a simple 3D engine (Without any use of API), successfully transformed my scene into world and view space but have trouble projecting my scene (from view space) using the perspective projection matrix (OpenGL style). I'm not sure about the fov, near and far values and the scene I get is distorted. I hope if someone can direct me how to build and use the perspective projection matrix properly with example codes. Thanks in advance for any help.

矩阵构建:

double f = 1 / Math.Tan(fovy / 2);
return new double[,] { 

    { f / Aspect, 0, 0, 0 },
    { 0, f, 0, 0 },
    { 0, 0, (Far + Near) / (Near - Far),  (2 * Far * Near) / (Near - Far) }, 
    { 0, 0, -1, 0 } 
};

矩阵使用:

foreach (Point P in T.Points)
{     
    .
    .     // Transforming the point to homogen point matrix, to world space, and to view space (works fine)
    .     

    // projecting the point with getProjectionMatrix() specified in the previous code :      

    double[,] matrix = MatrixMultiply( GetProjectionMatrix(Fovy, Width/Height, Near, Far) , viewSpacePointMatrix );

    // translating to Cartesian coordinates (from homogen):

    matrix [0, 0] /= matrix [3, 0];
    matrix [1, 0] /= matrix [3, 0];
    matrix [2, 0] /= matrix [3, 0];
    matrix [3, 0] = 1;
    P = MatrixToPoint(matrix);

    // adjusting to the screen Y axis:

    P.y = this.Height - P.y;

    // Printing...
}

推荐答案

以下是透视投影矩阵的典型实现.这里有一个很好的链接来解释一切OpenGL投影矩阵

Following is a typical implemenation of perspective projection matrix. And here is a good link to explain everything OpenGL Projection Matrix

void ComputeFOVProjection( Matrix& result, float fov, float aspect, float nearDist, float farDist, bool leftHanded /* = true */ )
{
    //
    // General form of the Projection Matrix
    //
    // uh = Cot( fov/2 ) == 1/Tan(fov/2)
    // uw / uh = 1/aspect
    // 
    //   uw         0       0       0
    //    0        uh       0       0
    //    0         0      f/(f-n)  1
    //    0         0    -fn/(f-n)  0
    //
    // Make result to be identity first

    // check for bad parameters to avoid divide by zero:
    // if found, assert and return an identity matrix.
    if ( fov <= 0 || aspect == 0 )
    {
        Assert( fov > 0 && aspect != 0 );
        return;
    }

    float frustumDepth = farDist - nearDist;
    float oneOverDepth = 1 / frustumDepth;

    result[1][1] = 1 / tan(0.5f * fov);
    result[0][0] = (leftHanded ? 1 : -1 ) * result[1][1] / aspect;
    result[2][2] = farDist * oneOverDepth;
    result[3][2] = (-farDist * nearDist) * oneOverDepth;
    result[2][3] = 1;
    result[3][3] = 0;
}

这篇关于如何构建透视投影矩阵(无 API)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆