简体   繁体   English

OpenGL ES 2.0 光线拾取,远点

[英]OpenGL ES 2.0 Ray Picking, far point

Help me please with 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 and _normalMatrix put to shader _modelViewProjectionMatrix 和 _normalMatrix 放入着色器

glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);

and in touch end并联系结束

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);

How I can get far point?我怎样才能得到远点? And my near_point is correct or not?我的 near_point 是否正确?

Thanks!谢谢!

it looks like you have看起来你有

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) to calculate the normalized device coordinates of the near point. (phew) 来计算近点的归一化设备坐标。

To get the far point, just swap the -1 z coordinate for a 1 :要获得远点,只需将-1 z 坐标换成1

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);

And apply the same inverse transform to that.并对其应用相同的逆变换。 That should do the trick.这应该够了吧。

Background: Under normal circumstances, the final coordinates received by the GL for turning a fragment into a pixel are what are called normalised device coordinates .背景:在正常情况下,GL最终接收到的将一个fragment变成一个像素的坐标就是所谓的normalized device coordinates These lie within a cube whose corners are at (-1,-1,-1_ and (1,1,1). So the center of the screen is (0,0,z), the top left corner is (-1,1,z) and so on. The coordinates are transformed so that a point lying on the near plane will have az coordinate of 1, and one lying just on the far plane will have az coordinate of -1. These are the numbers that are used for depth testing, if you have it turned on.它们位于一个立方体中,立方体的角位于 (-1,-1,-1_ 和 (1,1,1)。因此屏幕的中心是 (0,0,z),左上角是 (-1 ,1,z) 等等。坐标被变换,使得位于近平面上的点的 z 坐标为 1,而恰好位于远平面上的点的 z 坐标为 -1。这些是数字用于深度测试,如果你打开它的话。

So, as you might guess, when you want to convert a screen location back to a point in 3D space, you actually have a number of points to choose from - a line, in fact, stretching from the near plane to the far plane.因此,正如您可能猜到的那样,当您想要将屏幕位置转换回 3D 空间中的一个点时,您实际上有许多点可供选择 - 一条线,实际上是从近平面延伸到远平面。 In normalised device coordinates, this is the line stretching from z=-1 to z=1.在标准化设备坐标中,这是从 z=-1 延伸到 z=1 的线。 So the process goes like this:所以这个过程是这样的:

  • convert the x and y coordinates into normalised device coordinates x' and y'将 x 和 y 坐标转换为规范化的设备坐标 x' 和 y'
  • For each of z' = 1 and z' = -1:对于每个 z' = 1 和 z' = -1:
    • convert the coordinates to normalised device coordinates (see here for the formula )将坐标转换为规范化设备坐标(公式见此处
    • apply the inverse of the projection matrix应用投影矩阵的逆
    • apply the inverse of the model/view matrix (as it is before any per-object transformations)应用模型/视图矩阵的逆(就像在任何每个对象转换之前一样)

The results are the two coordinates of your line in 3D space.结果就是你的线在3D空间的两个坐标。

We can draw line from near_point to far_point .我们可以从near_pointfar_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);

    GLKMatrix4 inversedMatrix = GLKMatrix4Invert(_modelViewProjectionMatrix, nil);

    GLKVector4 near_point = GLKMatrix4MultiplyVector4(inversedMatrix, normalisedVector);

    near_point.v[3] = 1.0/near_point.v[3];
    near_point = GLKVector4Make(near_point.v[0]*near_point.v[3], near_point.v[1]*near_point.v[3], near_point.v[2]*near_point.v[3], 1);

    normalisedVector.z = 1.0;
    GLKVector4 far_point = GLKMatrix4MultiplyVector4(inversedMatrix, normalisedVector);

    far_point.v[3] = 1.0/far_point.v[3];
    far_point = GLKVector4Make(far_point.v[0]*far_point.v[3], far_point.v[1]*far_point.v[3], far_point.v[2]*far_point.v[3], 1);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM