我有一些球形经度/纬度坐标,用于我需要可视化的球体上的点。为此,我将点转换为笛卡尔坐标并构建了一个三角形网格,我可以使用VTK进行渲染。到目前为止工作。
现在我想为球体模型使用纹理。因此,我将球面坐标转换为纹理坐标,并将它们分配给每个点。这适用于球体的大多数表面三角形,结果看起来可以接受。
但是,对于纹理包裹的本初子午线对面的三角形,三角形纹理不正确:不是重复纹理和“在纹理边界上”映射,整个纹理被挤压到单个三角形。
以下是它的样子:
zick-zack线显然是错误的,蓝线应该是可见的。整个纹理映射在三角形上,产生红色和白色条纹。这是有道理的,因为对于所讨论的三角形,纹理坐标跨越整个纹理空间。
为了说明这个问题,这个问题并非特定于球体,而是所有封闭的物体,我创建了下图:
在上部矩形中,我们看到一个三角形跨越纹理边界,带有计算纹理坐标A,B和C.由于纹理可以平铺,这就是我想要渲染三角形的方式。
下三角显示当前如何解释纹理坐标。边A,B和C的坐标是相同的,但这次,大部分纹理用于三角形,而不是在边界处平铺纹理。
我确信我犯了一个很常见的错误,但我还没有找到任何帮助我的东西。对我有任何暗示吗?
答案 0 :(得分:5)
答案非常简单,您需要在边缘上映射纹理坐标。实现取决于您的数据集,但这是对此问题的准备。
在计算机图形中,纹理坐标存储在面上而不是顶点上,问题显示原因。当您在球体周围绘制纹理时,让我们以10个步骤开始,以0.0开始,然后以0.1为增量继续。如果沿着本初子午线使用纹理坐标,则会得到纹理坐标为0.9和0.0的面。图形硬件执行它所说的内容,并在0.0和0.9之间插入纹理。
要解决您的问题,您需要将纹理从0.9映射到1.0。
如果可以,可以使用其他纹理坐标创建多边形或复制有问题的顶点。
答案 1 :(得分:2)
首先,您可能不希望仅将球面坐标映射到覆盖球体的单个矩形纹理,因为纹素分辨率在表面上变得非常不均匀。
更好的方法是使用地图集。 “地图集”是将表面参数化为多个“图表”,每个“图表”是连接区域。例如,您可以将球体映射到大约6个与立方体的边相对应的图表上,并且每个图表将更好地保留球体部分的形状。您可以谷歌进行多图表参数化或类似的东西。如果你想走那条路,DirectX内置了UVAtlas。图表之间接缝处理的问题实际上更简单,因为三角形总是位于一个图表中,完全是一个不同的问题。
那就是说,要处理你的情况下的接缝,你需要知道(球形)网格的哪些三角形边缘与边界(子午线或其他)相交。然后,您必须将入射在这些边缘上的三角形分解为不跨越边界的碎片,并正确应用纹理坐标。
答案 2 :(得分:1)
回答一个非常古老的问题,因为我认为使用内置的vtk vtkSphereSource
方法会有更简单的答案。
你想要“破坏”球体,这样你就不会在球体周围得到0.9到0.0之间的纹理插值。在python中,调用sphere.SetEndTheta(360 - 1.e-4)
,这实际上会从球体中取出一小片。这样就可以让纹理的最终顶点集一直映射到1.0。