【问题标题】:UV Mapping issue artifact on Sphere OpenGlSphere OpenGL 上的 UV 映射问题工件
【发布时间】:2018-04-05 20:10:45
【问题描述】:

我正在使用公式在 3d 球体 X、Y、Z 坐标上对 2D 纹理进行 UV 映射

u = (0.5 + atan2(X, Y) / (2 * glm::pi<double>()));
v = (0.5 - asin(Z) / glm::pi<double>());

在现代 openGL C++ 中。

我不知道为什么球体中有这个神器。想不通。

【问题讨论】:

  • 我只注意到如果我通过添加更多顶点来增加球体的分割数和复杂性,这个工件会变得更薄。但它仍然存在。
  • 伪影发生在纹理坐标的翻转点(它们从 1 回到 0 的面。解决这个问题的唯一方法是复制一个顶点环,其中发生。然后将纹理坐标 0 分配给一个圆,将 1 分配给另一个圆。注意,您还必须调整索引。
  • @BDL 谢谢,所以这意味着在翻转点,片段着色器向后插值并将所有数据钳制在那个经度?
  • 是的,正是:)

标签: c++ opengl uv-mapping


【解决方案1】:

好的,我已经想通并纠正了这个问题,我想我现在终于可以在这里回答了。

非常感谢 BDL 和 Rabbid76。

每当 u == 0 时,我将相同的顶点位置 (X Y Z) 添加到顶点向量(或数组)并增加索引,但这次将纹理 u 硬编码为 1.0f。

现在没有问题,接缝看起来很完美。

【讨论】:

  • 你能澄清或显示一些代码..吗?我不明白你添加相同的顶点位置是什么意思..
【解决方案2】:

这是索引的纹理球体几何的详细信息。您应该使用 index 以获得更好的性能: m_meridians 和 m_latitudes 是球体的细节层次。

for (size_t i = 0; i < m_meridians + 1; i++)
{
    for (size_t j = 0; j < m_latitudes + 2; j++)
    {
        // texCoord in the range [(0,0), (1,1)]
       QVector2D texCoord((float)i / m_meridians, (float)j / (m_latitudes+1));
        // theta = longitude from 0 to 2pi
        // phi = latitude from -pi/2 to pi/2
        double theta, phi;
        theta = 2*M_PI * texCoord.x();
        phi = M_PI * texCoord.y() - M_PI_2;
        QVector3D pos;
        pos.setY((float)std::sin(phi));
        pos.setX((float)std::cos(phi) * std::cos(theta));
        pos.setZ((float)std::cos(phi) * std::sin(theta));

        m_vertices.push_back({pos, texCoord});
    }
}

// Calculate triangle indices

for (size_t i = 0; i < m_meridians; i++)
{
    // Construct triangles between successive meridians
    for (size_t j = 0; j < m_latitudes + 1; j++)
    {
        m_indices.push_back(i * (m_latitudes+2) + j);
        m_indices.push_back(i * (m_latitudes+2) + j+1);
        m_indices.push_back((i+1) * (m_latitudes+2) + j+1);

        m_triangleCount++;

        m_indices.push_back((i+1) * (m_latitudes+2) + j+1);
        m_indices.push_back((i+1) * (m_latitudes+2) + j);
        m_indices.push_back(i * (m_latitudes+2) + j);

        m_triangleCount++;
    }
}

【讨论】:

  • 如果你写了一个答案,你还应该解释最初的问题是什么以及为什么你的代码可以解决它。仅仅发布代码对未来的访问者没有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-27
  • 2011-07-15
  • 2013-12-07
  • 2011-08-20
  • 1970-01-01
  • 1970-01-01
  • 2011-08-30
相关资源
最近更新 更多