2009-10-03 51 views
4

我有一些球形经度/纬度坐标,用于需要形象化的球体上的点。为此,我将点转换为笛卡尔坐标,并构建了一个可以用VTK渲染的三角形网格。迄今为止工作。球体上的纹理错误

现在我想使用球体模型的纹理。因此我将球形坐标转换为纹理坐标并将其分配给每个点。这适用于球体的大部分表面三角形,并且结果看起来可以接受。

但是,对于素数子午线对面纹理包裹的三角形,三角形被错误地纹理化:不是重复纹理和映射“越过纹理边界”,整个纹理被挤压到单个三角形。

这里是它的外观像一个画面:

sphere-texture

的济科,扎克线显然是错误的,蓝线应该是可见的,而不是。整个纹理映射到三角形上,产生红色和白色条纹。这是有道理的,因为对于所讨论的三角形,纹理坐标跨越整个纹理空间。

为了说明这个问题,这是不特定的领域,但所有封闭的对象,我创建了如下图所示:

texture-seam

在上面的矩形,我们看到,横跨纹理三角形计算出的纹理坐标A,B和C的边界。由于纹理可以平铺,这就是我想要渲染三角形的方式。

下面的三角形显示当前如何解释纹理坐标。边A,B和C的坐标是相同的,但是这一次,大部分纹理用于三角形,而不是在边界处平铺纹理。

我相信我有一个很常见的错误,但我没有找到任何帮助我的东西。对我有任何提示吗?

+0

在过去的一天左右,我一直在为此苦苦挣扎,主要是在检测哪些面有错误。结果发现错误的面具有反时钟顺序的纹理坐标。 – 2011-12-07 21:00:29

回答

5

答案很简单,您需要将纹理坐标映射到边缘。实现取决于你的数据集,但这是一个刺探问题。

在计算机图形中,纹理坐标存储在面上而不是顶点上,并且问题显示原因。当你围绕一个球体绘制纹理时,让我们从0.0开始的10个步骤中说,然后以0.1为增量继续。如果沿着素数子午线使用纹理坐标,则会得到纹理坐标为0.9和0.0的面。图形硬件完成它所说的内容,并在0.0和0.9之间插入纹理。

要解决您的问题,您需要将纹理从0.9映射到1.0。

如果可以,可以使用这种方法创建多边形或使用其他纹理坐标复制违规顶点。

+0

复制一些顶点似乎是迄今为止最实际的解决方案 - 我会尝试一下。感谢提示。 – 2009-10-05 13:27:56

+0

您可否详细说明“以这种方式创建多边形?”我明白为什么会发生这种情况,但似乎不得不创建一排退化的面孔来修复接缝。 – 2011-10-16 17:20:20

+0

您不是创建退化的面,面是好的,只是得到具有纹理坐标0.0和1.0的重复顶点。如果您依赖连接信息,这是一个问题,但渲染和网格操纵是两回事。 – rioki 2011-11-01 13:49:35

2

首先,您可能不希望仅将球形坐标映射到覆盖球体的单个矩形纹理,因为纹理分辨率在表面上变得非常不均匀。

更好的方法是使用地图集。 “地图集”是将表面参数化为多个“图表”,每个“图表”都是连接区域。例如,您可以将球体映射到大致6个与立方体边相对应的图表,并且每个图表都会更好地保留球体部分的形状。你可以谷歌多图参数化或类似的东西。如果你想要走这条路线,DirectX已经建立在UVAtlas世代。由于三角形总是位于一个图表内,所以在图表之间的接缝处做什么的问题实际上更简单,并且完全是另一个问题。这就是说,为了处理你的案例中的接缝,你需要知道(球形)网格的哪个三角形边缘与边界(子午线或其他)相交。然后,您必须将这些边缘上的三角形分解为不跨越边界的碎片,并正确应用纹理坐标。

+0

感谢您为介绍地图集方法所做的努力。事实上,我想让事情变得简单,因为我只需要将数据可视化,而且我不开发游戏或类似的东西。我现在意识到我必须调整几何形状才能摆脱接缝,我会提出你的答案来指出这一点。 – 2009-10-05 13:26:56

1

回复一个非常古老的问题,因为我认为有一个更简单的答案,使用vtk的内置方法vtkSphereSource

您希望“打破”球体,以便在球体周围的0.9和0.0之间不会获得纹理插值。在python中,调用sphere.SetEndTheta(360 - 1.e-4),这实际上会从球体中取出一小块。这样就可以为纹理提供最终的一组顶点,一直映射到1.0。