简体   繁体   English

OpenGL中的3D拾取

[英]3D Picking in OpenGL

Is there a "standard" method for 3d picking? 是否有3D拾取的“标准”方法? What do most game companies do? 大多数游戏公司做什么? (for accurate picking) (用于精确拣选)

I thought the fastest way is to use the gpu and render every object with an "color index", and then to use glReadPixels() , but then I heard that it's considered slow because of glFlush() , glFinish() calls. 我认为最快的方法是使用gpu并使用“颜色索引”呈现每个对象,然后使用glReadPixels() ,但是随后我听说由于glFlush()glFinish()调用它被认为很慢。

There's also this ray casting approach, which is nice but isn't accurate because of the spheres/AABBs approximations. 还有一种射线投射方法,这种方法很好,但由于球体/ AABB近似,因此不够准确。

Any question about what is "standard" is probably going to invoke some opinionated responses, but I would suggest that the closest to "standard" here is raycasting. 关于什么是“标准”的任何问题都可能会引起一些自以为是的回答,但我建议此处最接近“标准”的是光线投射。

Take your watertight ray/triangle intersection function and test a ray that is unprojected from your mouse cursor position against the triangles in your scene. 采取水密射线/三角形相交功能,并测试从鼠标光标位置向场景中的三角形投射的射线。

Normally this would be quite slow, requiring linear complexity. 通常这会很慢,需要线性复杂度。 So the next step is to accelerate it to something better, like logarithmic time. 因此,下一步是将其加速到更好的状态,例如对数时间。 This is typically achieved with a data structure such as an octree, BVH, KD tree, or BSP. 通常使用数据结构(例如八叉树,BVH,KD树或BSP)来实现。 Sometimes people skip this step and just try to make the ray/tri intersection really fast and really parallel, possibly even using GPGPU. 有时人们会跳过此步骤,只是尝试使射线/三角交叉点真正快速且真正平行,甚至可能使用GPGPU。

It takes a lot more work upfront than framebuffer-based solutions, but complex applications tend to go this route probably because: 与基于帧缓冲区的解决方案相比,它需要大量的前期工作,但是复杂的应用程序倾向于采用这种方法,原因可能是:

  1. Portability: it's decoupled from the rendering engine. 可移植性:它与呈现引擎分离。 It doesn't have to be tied to OpenGL or DirectX, eg, and that improves portability. 例如,它不必与OpenGL或DirectX捆绑在一起,从而提高了可移植性。
  2. Generality: typically the accelerator and associated queries are needed for other things. 通用性:通常情况下,还需要加速器和关联的查询。 For example, an FPS game might have players and enemies constantly shooting at each other. 例如,FPS游戏可能会让玩家和敌人不断向对方开枪。 Figuring out what projectiles hit what tends to require these kinds of intersection queries occurring constantly, and not just from a uniform viewing angle. 弄清楚什么弹丸击中了什么,这就要求不断发生这种交叉查询,而不仅仅是从一个统一的视角。
  3. Simplicity: the developers can afford the extra work upfront to simplify things later on. 简便性:开发人员可以承担额外的前期工作,以简化以后的工作。

There's also this ray casting approach, which is nice but isn't accurate because of the spheres/AABBs approximations. 还有一种射线投射方法,这种方法很好,但由于球体/ AABB近似,因此不够准确。

There should be nothing inaccurate about using AABBs or bounding spheres for acceleration purposes. 将AABB或边界球用于加速目的应该没有任何不正确的地方。 Those are purely to accelerate the tests and quickly reduce the number of the more costly ray/triangle intersections that need to occur by doing cheaper tests and ones that eliminate large batches of triangles to check in bulk. 这些纯粹是为了加快测试速度,并通过进行更便宜的测试来快速减少需要发生的更昂贵的射线/三角形相交的数量,并消除大量的三角形来批量检查。 Normally they should be constructed to encompass the elements in the scene. 通常,应将它们构造为包含场景中的元素。 If you do a ray/AABB intersection first, eg, and if that hits, test the elements encompassed within the AABB. 例如,如果您首先进行ray / AABB相交,并且成功,请测试AABB中包含的元素。 Any acceleration structure that doesn't give the same results without the accelerator would typically be a glitchy one. 没有加速器就无法获得相同结果的任何加速结构通常都是小故障。

For example, a very basic form of acceleration is just put a bounding box around one mesh element in a scene, like a character, and sometimes this basic form without involving a full-blown accelerator might be useful for very dynamic elements in the scene (to avoid the cost of constantly updating the accelerator). 例如,一种非常基本的加速形式只是将包围盒放在场景中的一个网格元素(如角色)上,有时这种不涉及成熟加速器的基本形式可能对场景中非常动态的元素很有用(以避免不断更新加速器的成本)。 If the ray intersects the character's bounding box, then check all the triangles making up the character. 如果光线与角色的边界框相交,则检查构成角色的所有三角形。 As long as you check the triangles within the AABB afterwards, it becomes about acceleration rather than approximation. 之后,只要检查AABB中的三角形,它就变成加速度,而不是近似值。 Of course if you only checked the AABB and nothing else, then it would be a crude approximation. 当然,如果仅检查AABB而不是其他任何内容,那将是一个粗略的近似值。

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

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