OpenGL:使用球坐标在球体上映射纹理

OpenGL: Mapping texture on a sphere using spherical coordinates

我有一个地球纹理,我想将其映射到一个球体上。 由于它是一个单位球体并且模型本身没有纹理坐标,我能想到的最简单的事情就是为每个顶点计算球坐标并将它们用作纹理坐标。

textureCoordinatesVarying = vec2(atan(modelPositionVarying.y, modelPositionVarying.x)/(2*M_PI)+.5, acos(modelPositionVarying.z/sqrt(length(modelPositionVarying.xyz)))/M_PI);

在片段着色器中执行此操作时,效果很好,因为我从(插值的)顶点位置计算纹理坐标。

但是当我在顶点着色器中执行此操作时(如果模型本身具有纹理坐标,我也会这样做),我得到的结果如下图所示。顶点显示为点,纹理坐标 (u) 低于 0.5 为红色,而其他所有为蓝色。

所以看起来两个相邻 red/blue 顶点的纹理坐标 (u) 的值(几乎)为 1.0 和 0.0。然后变量被平滑地插值,因此产生介于 0.0 和 1.0 之间的值。这当然是错误的,因为该值应该是 1.0 或 0.0,但不能介于两者之间。

有没有一种方法可以将球坐标用作纹理坐标,而不会出现上面显示的那些效果? (如果可能的话,不改变模型)

这是一个常见问题。两个纹理坐标拓扑之间的接缝,您希望纹理坐标从 1.0 无缝环绕到 0.0,需要网格来正确处理它。为此,网格必须沿接缝复制每个顶点。其中一个顶点将具有 0.0 纹理坐标,并将连接到来自右侧的顶点(在您的示例中)。另一个将具有 1.0 纹理坐标,并将连接到来自左侧的顶点(在您的示例中)。

这是网格问题,最好在网格本身解决。同一个位置需要两个不同的纹理坐标,所以你必须复制有问题的位置。

或者,您可以让片段着色器从插值顶点法线生成纹理坐标。当然,这在计算上更昂贵,因为它需要从一个方向转换成一对角度(然后转换到 [0, 1] 纹理坐标范围)。