在OpenGL es 2.0中取消投影到世界的屏幕

时间:2014-10-07 23:36:20

标签: opengl-es android-ndk projection ray-picking

长时间听众,第一次来电。 所以我一直在玩Android NDK和我想要取消调整点击世界坐标但我无法使其工作。 问题是近点和远点的x和y值都是相同的,这对于透视投影来说似乎并不合适。场景中的所有内容都很好,所以我有点困惑,为什么它不能正确投影,无论如何这里是我的代码请帮助谢谢

//x and y are the normalized screen coords
ndk_helper::Vec4 nearPoint = ndk_helper::Vec4(x, y, 1.f, 1.f);
ndk_helper::Vec4 farPoint = ndk_helper::Vec4(x, y, 1000.f, 1.f);

ndk_helper::Mat4 inverseProjView = this->matProjection * this->matView;
inverseProjView = inverseProjView.Inverse();

nearPoint = inverseProjView * nearPoint;
farPoint = inverseProjView * farPoint;

nearPoint = nearPoint *(1 / nearPoint.w_);
farPoint = farPoint  *(1 / farPoint.w_);

1 个答案:

答案 0 :(得分:0)

那么,在查看ndk_helper中的向量/矩阵数学代码之后,这并不奇怪。简而言之:不要使用它。扫描几分钟后,它有一些明显的错误,看起来像简单的拼写错误。特别是Vec4类对于图形所需的矢量操作几乎没用。大多数操作都假设Vec4是4D空间中的向量,而不是包含3D空间中同质坐标的向量。

如果你愿意,你可以在这里查看,但要准备好几张脸掌:

https://android.googlesource.com/platform/development/+/master/ndk/sources/android/ndk_helper/vecmath.h

例如,这是代码最后两行中使用的乘法的实现:

Vec4 operator*( const float& rhs ) const
{
    Vec4 ret;
    ret.x_ = x_ * rhs;
    ret.y_ = y_ * rhs;
    ret.z_ = z_ * rhs;
    ret.w_ = w_ * rhs;
    return ret;
}

这会将4D空间中的矢量乘以标量,但如果使用齐次坐标运算则完全错误。这解释了您所看到的结果。

我建议你自己编写适合图形类型操作的矢量/矩阵库,或者使用一个免费提供的库,这些库经过测试,并被其他人使用。

顺便说一句,您用于测试的具体值看起来有些奇怪。你肯定不应该为这两个向量得到相同的结果,但它可能不是你想到的那样。对于输入向量中的z坐标,您使用眼坐标中近距离和远距离平面的距离。但随后您将逆视图投影矩阵应用于那些向量,这些向量将它们从剪辑/ NDC空间转换回世界空间。因此,此计算的输入向量应位于clip / NDC空间中,这意味着对应于近/远平面的z坐标值应为-1和1.