OpenGL—射线拾取(ray pick)
2014-10-12 13:18
183 查看
简介:
OpenGL中鼠标射线拾取,就是通过鼠标点击屏幕产生的坐标,通过变换到3D坐标空间,然后从摄像机原点与该3D空间坐标产生一个射线(ray),通过该射线与3D世界中的物体做相交检测,即可实现3D物体的拾取。实现:
从OpenGL—坐标变换中可以知道,当前鼠标的坐标属于视口坐标,所以需要取得当前鼠标点击的点在3D世界中的坐标位置,也就是要将当前鼠标的点通过逆变换,从视口坐标变换到世界坐标中,然后再与世界坐标中的物体做相交检测。2D视图坐标:
对于当前鼠标在屏幕中点击的点的坐标就是2D的视图坐标,该坐标就是windowsd的窗口坐标,窗口左上角(0, 0), 右下角为(w,h)。3D标准设备坐标(NDC):
也就是将当前的视图坐标转换为标准设备坐标即x的坐标从左往右为[-1, 1],y轴的坐标从上到下为[1, -1],z轴从外到里为[-1, 1],则将视图坐标转换为ndc坐标为:float x = (2.0f * mouse_x) / width - 1.0f; float y = 1.0f - (2.0f * mouse_y) / height; float z = 1.0f; vec3 ray_nds = vec3 (x, y, z);
z的坐标为1.0代表当前将鼠标的位置投影到远裁剪平面,如果设z的坐标为-1则代表将当前投影到近裁剪平面上。
4D裁剪坐标:
也就是为了将NDC坐标变换到四维齐次坐标,所以这步我们只需要加上w的值即可:vec4 ray_clip = vec4 (ray_nds.xyz, 1.0);
视觉坐标:
由于从视觉坐标变换到裁剪坐标是通过一个投影矩阵来变换的,所以在这我们只需要取得当前的投影矩阵,对投影矩阵求逆即可将坐标从裁剪坐标变换回到视觉坐标:vec4 ray_eye = inverse (projection_matrix) * ray_clip;
世界坐标:
由世界坐标变换到视觉坐标,则将当前的世界坐标与视图矩阵做变换,所以为了得到世界坐标,则取得当前的视图矩阵,将当前的视觉坐标与视图矩阵的逆矩阵做变换,即可得到当前的世界坐标:vec4 ray_world = inverse (view_matrix) * ray_eye;
由于我们当前的坐标是带w值的,所以我们除以w,然后取得当前摄像机的位置,即可得到当前的射线:
if (ray_world.w != 0.0) { ray_world.x /= ray_world.w; ray_world.y /= ray_world.w; ray_world.z /= ray_world.w; } vec3 ray_dir = normalise(ray_world.xyz - camera_position);
射线的起始位置就是摄像机的位置。
相关文章推荐
- Android OpenGL射线拾取&手势旋转(二)
- OpenGL: 通过射线求交实现物体的拾取
- Android OpenGL射线拾取&手势旋转(一) 推荐
- Android OpenGL射线拾取&手势旋转(二)
- Android OpenGL射线拾取&手势旋转(一)
- OpenGL 射线 拾取
- 理解OpenGL拾取模式(OpenGL Picking)
- 理解OpenGL拾取模式(OpenGL Picking)
- Modern OpenGL用Shader拾取VBO内单一图元的思路和实现(3)
- NeHe OpenGL第三十二课:拾取游戏
- OpenGL环境下的射线选择
- (转载)UE4的射线拾取--LineTraceSingle 和 LineTraceMulti
- 用OpenGL实现射线拣取对象
- OpenGL直线拾取
- Modern OpenGL用Shader拾取VBO内单一图元的思路和实现
- OGRE最简单的射线拾取详解
- Unity3D学习笔记07:射线Ray实现点击拾取
- <<opengl编程基础>> 3.13 拾取和选择模式
- OpenGL鼠标拾取
- OGRE最简单的射线拾取详解