You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

球体纹理映射旋转时出现暗带问题求助

解决球体纹理暗带问题

看起来你遇到的暗带问题主要来自三个地方:纹理坐标计算错误、索引生成逻辑有误,还有顶点着色器里的一个小类型不匹配。让我们一步步解决:


1. 修复顶点着色器的纹理坐标输入

你的顶点着色器里把纹理坐标声明成了vec3 aTexCoord,但实际你传入的是vec2类型的sphere_texcoords,这会导致GPU读取到未初始化的第三个分量,虽然你只取了xy,但可能引发奇怪的采样问题。修改成vec2即可:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord; // 修正为vec2类型
out vec4 vertexColor;
out vec2 TexCoord;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main() {
    gl_Position = projection * view * model * vec4(aPos, 1.0);
    vertexColor = vec4(0.5, 0.2, 0.5, 1.0);
    TexCoord = aTexCoord; // 直接赋值,无需额外转换
}

2. 正确计算球体纹理坐标

你之前用(x+1)/2和(y+1)/2生成UV的方式,会导致球体接缝处(theta=2π的位置)出现UV不连续,而且两极纹理会严重拉伸。正确的做法是直接用生成顶点时的theta和phi角度来计算UV:

for (int i = 0; i <= stacks; ++i) {
    float s = (float)i / (float)stacks;
    float theta = s * 2 * glm::pi<float>();
    for (int j = 0; j <= slices; ++j) {
        float sl = (float)j / (float)slices;
        float phi = sl * glm::pi<float>();
        
        const float x = cos(theta) * sin(phi);
        const float y = sin(theta) * sin(phi);
        const float z = cos(phi);
        
        sphere_vertices.push_back(radius * glm::vec3(x, y, z));
        // 用角度生成均匀UV:u对应水平环绕,v对应垂直方向(反转sl适配纹理Y轴方向)
        sphere_texcoords.push_back(glm::vec2(s, 1.0f - sl));
    }
}

这样生成的UV会均匀覆盖整个球体,接缝处的UV从1自然过渡到0(纹理默认重复模式),不会出现断裂。

3. 修复索引生成逻辑

你原来的索引循环逻辑有问题,导致接缝处的三角形拼接错误,进而出现暗带。正确的球体索引生成应该遍历每个栈和切片,生成四边形对应的两个三角形:

// 重新生成索引
sphere_indices.clear();
for (int i = 0; i < stacks; ++i) {
    for (int j = 0; j < slices; ++j) {
        // 计算当前四边形的四个顶点索引
        int topLeft = i * (slices + 1) + j;
        int topRight = topLeft + 1;
        int bottomLeft = (i + 1) * (slices + 1) + j;
        int bottomRight = bottomLeft + 1;
        
        // 第一个三角形:左上 -> 左下 -> 右上
        sphere_indices.push_back(topLeft);
        sphere_indices.push_back(bottomLeft);
        sphere_indices.push_back(topRight);
        
        // 第二个三角形:右上 -> 左下 -> 右下
        sphere_indices.push_back(topRight);
        sphere_indices.push_back(bottomLeft);
        sphere_indices.push_back(bottomRight);
    }
}

这个逻辑会正确连接每个相邻顶点,避免出现错误的三角形拼接。


做完这三个修改后,纹理应该能正常映射到球体上,旋转时的暗带也会消失。如果还是遇到接缝问题,可以显式确认纹理的环绕模式:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

内容的提问来源于stack exchange,提问作者George

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:50:31