将投影转换为正交光线投射

Convert projection to orthogonal raycast

我在 OpenGL 中有一个完全实现的工作引擎,支持带光线投射的投影相机。最近,我实现了一种正交相机类型,从视觉上看,它工作得很好。作为参考,这是我计算正交矩阵的方法:

double l = -viewportSize.x / 2 * zoom_;
double r = -l;
double t = -viewportSize.y / 2 * zoom_;
double b = -t;
double n = getNear();
double f = getFar();

m = Matrix4x4(
    2 / (r - l),
    0,
    0,
    -(r + l) / (r - l),
    0,
    2 / (t - b),
    0,
    -(t + b) / (t - b),
    0,
    0,
    -2 / (f - n),
    -(f + n) / (f - n),
    0,
    0,
    0,
    1);

但是,我现在的问题是光线投射不适用于正交相机。问题似乎是光线投射引擎在编码时考虑了投影型相机,因此当使用正交矩阵时它会停止运行。作为参考,下面是如何实现光线投射的高级描述:

  1. 获取世界-space原点向量

    • 从输入屏幕坐标获取归一化屏幕坐标
    • 构建 mouseVector = (normScreenCoords.x, normScreenCoords.y, 0 if "near" or 1 if "far"
    • 构建视图-投影矩阵(从Camera获取视图和投影矩阵并相乘)
    • 将 mouseVector 乘以视图投影矩阵的逆矩阵。
  2. 获取world-space前向向量

    • 获取鼠标世界坐标(远)并从鼠标世界坐标(近)中减去它们
  3. 将 world-space origin 和 world-space 前向向量发送到光线投射引擎,该引擎处理将这些向量与所有可见对象进行比较的逻辑通过使用边界框高效场景。

如何修改此算法以使用正交相机?

您的步骤很好,在正交相机上应该可以正常工作。您计算原点和方向的方式可能有问题。

1.) 获取原点向量。首先以 world-space 为单位计算鼠标位置,即 float rayX = (mouseX - halfResolution) / viewport.width * (r - l) 或类似的。它应该是偏移的,所以屏幕的中心是 (0, 0),鼠标可以到达的极值转换到视口的边缘 l, r, t, b。然后从相机在世界中的位置 space 开始,添加两个向量 rayX * camera.local.rightrayY * camera.local.up,其中 rightup 是相机局部坐标系中的单位向量坐标系.

2.) 世界 space 前向矢量始终是任何鼠标位置的摄像机前向矢量。

3.) 只要您拥有 1 和 2 的正确向量,这应该无需修改即可工作。