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

Har*_*rry 4 c++ opengl textures glsl

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

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

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

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

纹理映射到球体上

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

有没有一种方法可以将球面坐标用作纹理坐标,而不会获得上面显示的效果?(如果可以的话,不改变型号)

Nic*_*las 5

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

这是一个网格问题,最好在网格本身中解决。同一位置需要两个不同的纹理坐标,因此您必须复制相关位置。

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