在平面上投影三维三角形网格时,如何得到仅可见表面的二维网格



如果我有一个三角形网格表面,它可以根据任何计算机图形渲染来渲染,并且只有最前面的三角形是可见的。

我感兴趣的是类似于概念上的渲染问题,但我不想要位图图像。我想要的是将3D三角形网格投影到平面上时产生的2D多边形列表,我需要的是生成的2D网格的实际顶点和边缘。

除了将完全可见的三角形投射到平面上(这是微不足道的)之外,这还意味着不包括完全覆盖的三角形,还意味着将部分覆盖的三角形剪切成具有>3条边的多边形。

简单地说,我可以简单地将每个三角形投影到平面上,跟踪每个三角形的z值,然后将每个三角形与其他多边形进行重叠比较,然后在必要时进行剪切和忽略。但这将是N^2,我必须多次执行这个过程,并且会考虑计算成本。

虽然我发现了很多关于三角形网格的操作,如渲染,简化,执行布尔值等。我还没见过。如果有这样做的库,或者讨论如何做到这一点的参考资料,我将不胜感激。

有两种方法。

。使用OpenGL/GPU(计算速度更快)(此逻辑也用于选择实现)

你必须遵循以下步骤(我假设你知道渲染管道和意识到OpenGL/WebGL)

  1. 把你的相机放在你想要投影几何体的平面上,设置适当的项目类型和其他相机参数
  2. 获取所有三角形的列表
  3. 为每个三角形指定一个唯一的颜色。下面是一种简单的方法,可以根据列表中三角形的索引来分配唯一的颜色。
int i = // Index of the triangle 
// We've added 1 to the index because 0 index is translated to black color 
// And our background is also rendered as black so we skip will that color.
int r = (i + 1 & 0x000000FF) >> 0;
int g = (i + 1 & 0x0000FF00) >> 8;
int b = (i + 1 & 0x00FF0000) >> 16;
glm::vec4 unique_color = glm::vec4(r / 255.0f, g / 255.0f, b / 255.0f, 1.0);
  1. 设置OpenGL标志的方式,你想要得到的结果,像打开背面剔除,启用深度测试和设置适当的深度功能等,这样你现在切断所有的三角形面对远离相机/平面,深度测试将过滤只有可视三角形从所有面向前方的三角形基于他们的深度。
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK); // This is the default value so you may skip
glFrontFace(GL_CCW); // Define winding of front-facing triangle.(default is GL_CCW)
  1. 创建一个帧缓冲区,并渲染所有的三角形与他们唯一分配的颜色。
  2. 当渲染完成后,你现在可以遍历所有像素,并从图像中获得唯一颜色列表。
  3. 将颜色解码为三角形的索引,如下所示。(这正是我们在步骤3中所做的反转)
int triangle_index =
color.r +
color.g * 256 +
color.b * 256 * 256;
  1. 有了这些三角形索引,你可以拿出我们在第2步中准备的三角形列表。
  2. 现在你有了所有在定义平面上可见的三角形。
  3. 你现在可以在平面上投影所有的三角形(三角形点),你可以在给定的平面上投影点、线和三角形。
  4. 您可以在这里阅读更多关于此技术的信息,此技术在本例中用于选择和拾取,http://www.opengl-tutorial.org/miscellaneous/clicking-on-objects/picking-with-an-opengl-hack/

B。使用CPU渲染器或编写自定义算法。

在这种情况下,您可以使用CPU渲染库进行相同的操作,或者您可以编写以下算法

  1. 计算我们想要投影可见三角形的平面的法线我们将其命名为projection_normal
  2. 丢弃所有法线与投影法线夹角大于90度的三角形。在这一步中,你基本上是在做背面剔除。
  3. 现在在投影平面上投影所有剩余的三角形。
  4. 识别重叠的投影三角形,只保留与平面距离最小(深度)的三角形,丢弃其余重叠的三角形。
  5. 在这里,你必须在上面的步骤中使用更多的计算几何数学来找到重叠,并且根据你如何计算倾斜三角形的深度可能会有不同的结果。

我总是推荐OpenGL方法,因为它具有处理速度更快的优势,因为我们使用GPU进行渲染。它为你做了大部分的工作,你可以根据你如何设置深度函数,人脸剔除标志等来控制结果。