【发布时间】:2014-07-24 11:00:04
【问题描述】:
Most efficient algorithm to calculate vertex normals from set of triangles for Gouraud shading 没有重复,因为没有讨论边缘检测问题。
如何计算三角几何中每个顶点的法线,以便在 Gouraud 着色器中使用以获得良好的显示效果,但要跟踪边缘?是否有免费、快速和高性能的标准解决方案?
我被分配了上述任务来修复产生可见伪影的例程。法线应该是一个简单的 Gouraud 着色器的输入数据,以“平滑”相干面上显示的几何图形。该例程还应该能够找到边缘,以便以后可以被软件的其他部分使用,而不会被“平滑”。
数据是从不包含任何法线信息的 .stl 文件中读取的,因此必须使用三角形的坐标计算所有面法线。
这是没有插值的几何图形:
这是插值算法目前所做的:
圆形平原看起来很好,但在平坦表面旁边发现的边缘强度不足以触发边缘检测算法,但也没有弱到不可见的地方,插值严重失败。结果是一个错位的法线传播到整个三角形。
我想知道是否有一个标准的解决方案,因为在使用这种类型的几何图形时应该经常出现这个问题。即使没有,你们中是否有人知道这项任务的常见问题以及如何避免这些问题以获得一些不错的结果?
任何帮助将不胜感激!
编辑:关于算法: 边缘检测不仅仅是关于三角形法线。请考虑以下示例(问题在 3D 中基本相同):
所有顶点共享相同的角度,即 30°。 (角度不完全正确,但你明白了......)但是,只有外部两个应该被识别为边缘,所以必须有另一个与这个问题相关的度量。到目前为止,我已经尝试了一个三角形的
- 圆周半径
- 最长边
- GTS triangle quality measure
可以修改两个三角形被认为共享一条边的“最小角度”。最长边的方法看起来最有前途(虽然远非完美),但我觉得还是有一些我忽略了...
【问题讨论】:
-
边缘“检测”是什么意思?如果两个共享一条边的三角形的表面法线足够不同(例如足够小的点积),是否认为它们之间存在“硬边”,否则不是?
-
无论如何,我认为您需要做的是按顺时针顺序查看给定顶点 v 周围的“硬”边,并考虑它们将接触 v 的三角形划分为 1 个或多个部分,每个由三角形的“路径”组成,其中路径中的相邻三角形共享“软”边缘。然后对于分区中的每个部分,您需要为 v 计算一个单独的顶点法线,并将其用于 Gouraud 着色该部分。如果 v 上没有硬边事件,或者有 2 个或更多的硬边,则此方法有效——唯一的问题是如果恰好有 1 个,然后我不知道应该做什么。
-
@j_random_hacker ->第一条评论:没错,但不幸的是,他们是否共享“硬”边缘的决定不仅取决于法线,还取决于三角形的尺寸. -> 第二条评论,这正是问题所在。既然可以发图了,那我就详细说说我目前所做的,也许问题会更清楚。
-
你试过到边缘对面顶点的距离吗?
标签: c++ algorithm geometry vertex normals