ios - OpenGL ES 2.0 光线拾取,远点

标签 ios opengl-es-2.0 coordinate-systems ray-picking

请帮我挑选光线

float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(35.0f), aspect, 0.1f, 1000.0f);

GLKMatrix4 modelViewMatrix = _mainmodelViewMatrix;


    // some transformations

_mainmodelViewMatrix = modelViewMatrix;

_modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
_normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);

_modelViewProjectionMatrix 和 _normalMatrix 放入着色器
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);

并在联系结束
GLKVector4 normalisedVector = GLKVector4Make((2 * position.x / self.view.bounds.size.width - 1),
                                             (2 * (self.view.bounds.size.height-position.y) / self.view.bounds.size.height - 1)   ,  //1 - 2 * position.y / self.view.bounds.size.height,
                                               -1,
                                               1);
GLKMatrix4 inversedMatrix = GLKMatrix4Invert(_modelViewProjectionMatrix, nil);


GLKVector4 near_point = GLKMatrix4MultiplyVector4(inversedMatrix, normalisedVector);

我怎样才能得到远点?我的 near_point 是否正确?

谢谢!

最佳答案

看起来你有

GLKVector4 normalisedVector = GLKVector4Make((2 * position.x / self.view.bounds.size.width - 1),
   (2 * (self.view.bounds.size.height-position.y) / self.view.bounds.size.height - 1) ,
   -1, 1);

(phew) 计算近点的归一化设备坐标。

要获得远点,只需交换 -1 1 的 z 坐标:
GLKVector4 normalisedFarVector = GLKVector4Make((2 * position.x / self.view.bounds.size.width - 1),
   (2 * (self.view.bounds.size.height-position.y) / self.view.bounds.size.height - 1) ,
   1, 1);

并对其应用相同的逆变换。这应该够了吧。

背景:在正常情况下,GL接收到的用于将片段转换为像素的最终坐标是所谓的标准化设备坐标。它们位于角在 (-1,-1,-1_ 和 (1,1,1) 的立方体内。所以屏幕的中心是 (0,0,z),左上角是 (-1 ,1,z) 以此类推。坐标被转换,使得位于近平面上的点的 z 坐标为 1,而位于远平面上的点的 z 坐标为 -1。这些是用于深度测试,如果你打开它的话。

因此,正如您可能猜到的,当您想将屏幕位置转换回 3D 空间中的一个点时,您实际上有许多点可供选择 - 实际上是一条从近平面延伸到远平面的线。在标准化设备坐标中,这是从 z=-1 延伸到 z=1 的线。所以过程是这样的:
  • 将 x 和 y 坐标转换为标准化的设备坐标 x' 和 y'
  • 对于 z' = 1 和 z' = -1 中的每一个:
  • 将坐标转换为标准化的设备坐标(见 here for the formula)
  • 应用投影矩阵的逆
  • 应用模型/ View 矩阵的逆矩阵(在任何每个对象转换之前)

  • 结果是您的线在 3D 空间中的两个坐标。

    关于ios - OpenGL ES 2.0 光线拾取,远点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10008688/

    相关文章:

    ios - 使用 WKWebView 创建自定义 ORKStep

    c++ - 安卓 OpenGL ES 2.0 : Can a GL_FLOAT texture be assigned to a FBO as a COLOR attachment?

    java - 将 2d vector 作为 vec4 传递到 OpenGL ES 2.0 着色器

    javascript - 使用proj4和EPSG代码变换成不同的坐标系

    cocoa-touch - iOS 应用程序因 'message sent to deallocated instance' 而崩溃

    iphone - 如何将特定的电子邮件收件人添加到我的 sharekit 项目?

    objective-c - 以编程方式查找区域

    android - GLSL - 顶点属性中的错误数据

    javascript - bbox 的 jVectorMap 坐标

    php - 如何在 R^2 中进行旋转?