在光线跟踪器中的摄影机设置中设置上方向向量



我正在阅读计算机图形学的基础知识,并试图建立自己的光线跟踪器。这本书说:"构造相机框架的最常见方法是从视点,即e,即视角方向,即−w,以及上向量,该向量用于构造在由视角方向和上方向定义的平面中具有v和w的基"

但后来我遇到了如何在光线跟踪器中移动相机?这意味着我们需要通过与相机方向(w)进行叉积来校正(斜率?)的向上矢量。为什么?

我用lookAt(0,0,0)和up(0,1,0)调用我的相机设置

// a camera can be constructed using a position, direction and an up vector
Camera::Camera(Vector position, Vector lookAt, Vector up) {
    this->position = position;
    this->lookAt = lookAt;
    // the difference between camera position and where we want
    // to look at is the direction of the camera
    Vector direction = lookAt.diff(position);
    // camera frame
    w = direction.normalize();
    v = up.cross(w).normalize(); // right vector

    // which is the correct up?
    u = up.normalize();
    printf("%.2f %.2f %.2fn", u.getX(), u.getY(), u.getZ()); // prints 0 1 0
    u = v.cross(w).normalize(); // the up vector
    printf("%.2f %.2f %.2fn", u.getX(), u.getY(), u.getZ()); // prints 0.31 -0.86 -0.41
}

最终需要的是一对向量,它们形成图像平面的正交基。其中一个将指向相对于相机方向的右侧。另一个是相对于摄影机的方向指向上。

如果向上矢量是一般的"天空就是这样",如果你的相机不是水平的,那么向上矢量和相机向上矢量会略有不同。向上矢量是关于所需方向的提示,但它并不完全是正确的矢量。在这种情况下,你可以将右向量与方向向量相交,这将给你一个位于图像平面中的向量,垂直于右向量。这就是你想要的。

如果向上矢量是一般的"天空就是这样",并且如果你的相机级别,那么向上矢量和camera_up矢量将完全相同。额外的叉积是不必要的,但如果您希望代码足够通用以处理第一种情况,那么它也没有害处。

也许一些ASCII艺术可以帮助澄清。。。

^                                        * look-at point
| "up"        "camera up"
|                   
|       image plane 
                     
                 "camera down"

向上矢量是直线向上的。观察点比相机高,所以相机必须向后倾斜一点。在图中,我们看到了图像平面的边缘。"右"向量在那个平面上,并在图中指出。方向向量(您的代码称之为w)垂直于图像,并直接指向观察点。

相机上方向矢量(代码中的u)必须位于图像平面中,所以我们不能只使用"上"。它必须垂直于"右"向量。最简单的方法是将这两个向量交叉。

由于我们根据原始向上向量生成了"右"向量,这就给了我们方向。

最新更新