从 2D 投影映射回 3D 点云

发布于 2024-10-31 00:06:36 字数 327 浏览 0 评论 0原文

我有一个由点顶点 (XYZ) 和最终三角形面组成的 3D 模型。 使用 OpenGL 或相机视图矩阵投影,我可以将 3D 模型投影到 2D 平面,即视图窗口或具有 m*n 分辨率的图像。

问题是如何确定 2D 投影平面中的像素与其原始 3D 模型中对应的顶点(或面)之间的对应关系。

即,
对于 2D 投影的给定像素,3D 模型中最接近的顶点是什么?
这听起来像是在挑选 openGL 或光线追踪问题。然而有什么简单的解决方案吗?

光线追踪的思想实际上是从一个视点找到与光线相交的第一个顶点/面。有人可以给我看一些教程或示例吗?我想找到一种独立于使用 OpenGL 的算法。

I have a 3D model consisting of point vertices (XYZ) and eventually triangular faces.
Using OpenGL or camera-view-matrix-projection I can project the 3D model to a 2D plane, i.e. a view window or an image with m*n resolution.

The question is how can I determine the correspondence between a pixel from the 2D projection plan and its corresponding vertex (or face) from the original 3D model.

Namely,
What is the closest vertices in 3D model for a given pixel from 2D projection?
It sounds like picking in openGL or raytracing problem. Is there however any easy solution?

With the idea of ray tracing it is actually about finding the first vertex/face intersected with the ray from a view point. Can someone show me some tutorial or examples? I would like to find an algorithm independent from using OpenGL.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

她说她爱他 2024-11-07 00:06:44

OpenGL 中的命中测试通常无需光线追踪即可完成。相反,在渲染每个图元时,输出中的平面用于存储图元的唯一 ID。命中测试就像读取光标位置处的 ID 平面一样简单。

Hit testing in OpenGL usually is done without raytracing. Instead, as each primitive is rendered, a plane in the output is used to store the unique ID of the primitive. Hit testing is then as simple as reading the ID plane at the cursor location.

喵星人汪星人 2024-11-07 00:06:44

我的(可能是天真的)想法是创建一个顶点数组,然后在投影到屏幕点后按距离(或距离平方,速度)对它们进行排序。列表中的第一项将是最接近的。 n 个顶点的复杂度为 O(n),但也不会更糟。

编辑:速度和内存更好:只需循环所有顶点并跟踪投影最接近视口像素(距离平方)的顶点。这假设您能够自己执行投影,而不依赖 OpenGL。

例如,在伪代码中:

function findPointFromViewPortXY( pointOnViewport )
  closestPoint = false
  bestDistance = false
  for (each point in points)
    projectedXY     = projectOntoViewport(point)
    distanceSquared = distanceBetween(projectedXY, pointOnViewport)
    if bestDistance==false or distanceSquared<bestDistance
      closestPoint = point
      bestDistance = distanceSquared
  return closestPoint

My (possibly-naive) thought would be to create an array of the vertices and then sort them by their distance (or distance-squared, for speed) once projected to your screen point. The first item in the list will be closest. It will be O(n) for n vertices, but no worse.

Edit: Better for speed and memory: simply loop through all vertices and keep track of the vertex whose projection is closest (distance squared) to your viewport pixel. This assumes that you are able to perform the projection yourself, without relying on OpenGL.

For example, in pseudo-code:

function findPointFromViewPortXY( pointOnViewport )
  closestPoint = false
  bestDistance = false
  for (each point in points)
    projectedXY     = projectOntoViewport(point)
    distanceSquared = distanceBetween(projectedXY, pointOnViewport)
    if bestDistance==false or distanceSquared<bestDistance
      closestPoint = point
      bestDistance = distanceSquared
  return closestPoint
九公里浅绿 2024-11-07 00:06:44

除了 Ben Voigt 的回答之外:

  1. 如果您对可拾取对象进行单独传递,则可以将视口设置为仅包含您将读取的单个像素。

  2. 您还可以使用几何着色器 (gl_PrimitiveID) 对三角形 ID 进行编码。

In addition to Ben Voigt's answer:

  1. If you do a separate pass over pickable objects, then you can set the viewport to contain only a single pixel that you will read.

  2. You can also encode triangle ID by using geometry shader (gl_PrimitiveID).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文