OpenGL本身支持基于图像空间的拾取,这里指的是几何拾取,即由屏幕点击触发一条射线,然后和场景中的物体求交,进而判断是否拾取到物体。现在先把OpenGL的投影矩阵和视口变换矩阵列出来:
OpenGL的投影矩阵:
OpenGL的视口变换矩阵:
假设鼠标点击屏幕(X,Y)位置,现在把它逆变换到NDC空间,假设其坐标为(Xn,Yn),结合视口变换矩阵可以求得:
Xn = ( X - (Vr + Vl)/2 ) / (Vr-Vl)/2 = ( X - VP_Center_X ) / Half_VP_Width
Yn = ( Y - (Vt + Vb)/2 ) / (Vt-Vb)/2 = ( Y - VP_Center_Y ) / Half_VP_Height
上面的参数分别代表视口的中心以及视口的宽度和高度。
接下来要把NDC坐标(Xn,Yn)变换到投影面坐标P(Xp,Yp)以构造拾取射线,现在假设在视图空间中有某个点(Xe,Ye,Ze)刚好投影到P点,则根据投影矩阵可得到下式:
Xn = -2n/(r-l)Xe/Ze - (r+l) / (r-l)