简体   繁体   English

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

[英]OpenGL: Mapping texture on a sphere using spherical coordinates

I have a texture of the earth which I want to map onto a sphere. 我有一个地球的纹理,我想要映射到一个球体上。 As it is a unit sphere and the model itself has no texture coordinates, the easiest thing I could think of is to just calculate spherical coordinates for each vertex and use them as texture coordinates. 因为它是一个单位球体而且模型本身没有纹理坐标,所以我能想到的最简单的方法就是计算每个顶点的球面坐标并将它们用作纹理坐标。

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

When doing this in the fragment shader, this works fine, as I calculate the texture coordinates from the (interpolated) vertex positions. 在片段着色器中执行此操作时,这很好,因为我从(插值的)顶点位置计算纹理坐标。

But when I do this in the vertex shader, which I also would do if the model itself has texture coordinates, I get the result as shown in the image below. 但是当我在顶点着色器中执行此操作时,如果模型本身具有纹理坐标,我也会这样做,我得到的结果如下图所示。 The vertices are shown as points and a texture coordinate (u) lower than 0.5 is red while all others are blue. 顶点显示为点,低于0.5的纹理坐标(u)为红色,而其他所有为蓝色。

纹理映射到球体上

So it looks like that the texture coordinate (u) of two adjacent red/blue vertices have value (almost) 1.0 and 0.0. 因此看起来两个相邻的红色/蓝色顶点的纹理坐标(u)具有值(几乎)1.0和0.0。 The variably is then smoothly interpolated and therefore yields values somewhere between 0.0 and 1.0. 然后可变地进行平滑插值,因此产生介于0.0和1.0之间的值。 This of course is wrong, because the value should either be 1.0 or 0.0 but nothing in between. 这当然是错误的,因为值应该是1.0或0.0,但两者之间没有任何关系。

Is there a way to work with spherical coordinates as texture coordinates without getting those effects shown above? 有没有办法使用球面坐标作为纹理坐标而不会获得上面显示的那些效果? (if possible, without changing the model) (如果可能,不改变模型)

This is a common problem. 这是一个常见问题。 The seams between two texture coordinate topologies, where you want the texture coordinate to seamlessly wrap from 1.0 to 0.0 requires the mesh to properly handle this. 两个纹理坐标拓扑之间的接缝,您希望纹理坐标从1.0无缝地换行到0.0,这需要网格正确处理它。 To do this, the mesh must duplicate every vertex along the seam. 为此,网格必须沿着接缝复制每个顶点。 One of the vertices will have a 0.0 texture coordinate and will be connected to the vertices coming from the right (in your example). 其中一个顶点将具有0.0纹理坐标,并将连接到来自右侧的顶点(在您的示例中)。 The other will have a 1.0 texture coordinate and will be connected to the vertices coming from the left (in your example). 另一个将具有1.0纹理坐标,并将连接到来自左侧的顶点(在您的示例中)。

This is a mesh problem, and it is best to solve it in the mesh itself. 这是一个网格问题,最好在网格本身中解决它。 The same position needs two different texture coordinates, so you must duplicate the position in question. 相同的位置需要两个不同的纹理坐标,因此您必须复制相关位置。

Alternatively, you could have the fragment shader generate the texture coordinate from an interpolated vertex normal. 或者,您可以让片段着色器从插值顶点法线生成纹理坐标。 Of course, this is more computationally expensive, as it requires doing a conversion from a direction to a pair of angles (and then to the [0, 1] texture coordinate range). 当然,这在计算上更昂贵,因为它需要从一个方向转换到一对角度(然后到[0,1]纹理坐标范围)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM