透视投影,正典视角量

问题描述 投票:1回答:1
Vector3d nearC(0,0,0 -w);
Vector3d farC(0,0,0-x);
double width = y/2;
double height = z/2;
double angleOfHeight = atan(height/w);
double angleOfWidth = atan(width/w);
double adjustedHeight = tan(angleOfHeight) * x;
double adjustedWidth = tan(angleOfWidth) * x;

nearC[0] - width, nearC[1] - height, nearC[2]
nearC[0] - width, nearC[1] + height, nearC[2]
nearC[0] + width, nearC[1] + height, nearC[2]
nearC[0] + width, nearC[1] - height, nearC[2]
farC[0] - adjustedWidth, farC[1] - adjustedHeight, farC[2]
farC[0] - adjustedWidth, farC[1] + adjustedHeight, farC[2]
farC[0] + adjustedWidth, farC[1] + adjustedHeight, farC[2]
farC[0] + adjustedWidth, farC[1] - adjustedHeight, farC[2]

以上是我的frustum的视图坐标。视图矩阵是。

 0   0  -1   0
 0   1   0  -1
 1   0   0 -10
 0   0   0   1

所有的都是正确的,我们有一个表。

我怎么也想不明白怎么才能让那个frustum变成规范的视角体积。我跑遍了所有能找到的透视投影。目前是这样的

        s,        0,                      0,                     0,
        0,        s,                      0,                     0,
        0,        0,             -(f+ne)/(f-ne),            2*f*ne/(f-ne),
        0,        0,                      1,                     0;

double s = 1tan(angleOfView * 0. 5 * M_PI 180);

我少了一个步骤或什么,对吗?还是少了几步?

对不起,现在听起来很无奈,已经在这个问题上转了好一阵子了。

感谢任何帮助。

opengl perspective frustum
1个回答
2
投票

先从透视投影说起。在旧GL中常见的方法是使用 gluPerspective.

为此,我们需要 znear,zfar,FOV 和视角的长宽比。更多信息请看。

  • 根据视图平面计算透视投影矩阵。

    我习惯于使用 FOVx (视角在 x 轴)。) 要计算出这一点,你需要从上面看xz平面(在相机空间)的挫折。

    frustrum XY plane

    所以:

    tan(FOVx/2) = znear_width / 2*focal_length
    FOVx = 2*atan(znear_width / 2*focal_length)
    

    所以: 焦距可以通过计算挫折边线的交点来计算。或者使用三角形相似性。第二种比较容易写。

    zfar_width/2*(|zfar-znear|+focal_length) = znear_width/2*(focal_length)
    zfar_width/(|zfar-znear|+focal_length) = znear_width/(focal_length)
    focal_length = (|zfar-znear|+focal_length)*znear_width/zfar_width
    focal_length - focal_length*znear_width/zfar_width = |zfar-znear|*znear_width/zfar_width 
    focal_length*(1-(znear_width/zfar_width)) = |zfar-znear|*znear_width/zfar_width 
    focal_length = (|zfar-znear|*znear_width/zfar_width) / (1-(znear_width/zfar_width))
    

    这就是我们所需要的一切,所以:

    focal_length = (|zfar-znear|*znear_width/zfar_width) / (1-(znear_width/zfar_width))
    FOVx = 2*atan(znear_width / 2*focal_length)        
    FOVx*=180.0/M_PI; // convert to degrees
    aspect=znear_width/znear_height;
    gluPerspective(FOVx/aspect,aspect,znear,zfar);
    

    所以: |zfar-znear| 是平面之间的垂直距离 !!! 所以,如果你没有轴对齐的,那么你需要计算,使用点积和法线......

© www.soinside.com 2019 - 2024. All rights reserved.