地球纹理重叠

我正在尝试使用opengl渲染地球。因此,我要做的是,首先通过在几何着色器中操纵常规二十面体的点来制作球体。我使用点的坐标作为纹理坐标来采样地球的立方图。这是代码:

顶点着色器:

顶点着色器仅接受二十面体点,并将它们未经修改地传递给几何着色器。因此,我没有发布顶点着色器。

几何着色器:

几何着色器将三角形划分为较小的三角形。我认为这就是错误所在。

#version 440 core

uniform float radius;
layout (triangles) in;
layout (triangle_strip, max_vertices = 196) out;
uniform mat4 projectionview;

//The model matrix
uniform mat4 spModel;

//Texture stores texture coordinates.
out vec3 Texture;

//A structure to store three points of a triangle. Note that as a convention, I have stored points in a particular order.
// to use face cull.
struct triangle{
    vec4 pUp;
    vec4 pLeft;
    vec4 pRight;
};

//please read the function definitions before moving on to the main function.
triangle returnMidTriangle(triangle T);
vec4 makeSpherePoint(vec4 v);
vec3 returnNormal(triangle T);
void printTriangle(triangle T);
void getSubTriangles(triangle T, inout triangle array[4]);

void main()
{

    triangle initialT;
    initialT.pUp = gl_in[0].gl_Position;
    initialT.pLeft = gl_in[1].gl_Position;
    initialT.pRight = gl_in[2].gl_Position;

    triangle initSubT[4], subTsubT[4], subTsubTsubT[4];

    getSubTriangles(initialT, initSubT);

    for(int k = 0;k<=3;k++)
    {
        getSubTriangles(initSubT[k], subTsubT);
        for(int j = 0;j<=3;j++)
        {
            getSubTriangles(subTsubT[j], subTsubTsubT);
            for(int p = 0;p<=3;p++)
            {
                printTriangle(subTsubTsubT[p]);
            }
        }
    }


}

//This function transforms a given point on to the sphere.
vec4 makeSpherePoint(vec4 v)
{
    return projectionview*spModel*vec4(radius*normalize(vec3(v)),1.0f);
}

//This function returns the triangle formed by joining midpoint of sides of triangle. Note the returned triangle also follows the same convention.
triangle returnMidTriangle(triangle T)
{
    triangle mid;
    mid.pUp = (T.pUp + T.pLeft)/2;
    mid.pLeft = (T.pLeft + T.pRight)/2;
    mid.pRight = (T.pRight + T.pUp)/2;
    return mid;
}

//This function divides a triangle into four triangles and returns an array of them. The triangles are stored in the array as follows: 0 - Top 1 -Left
//2 - right 3 - mid. Even in each individual sub-triangle the convention is still followed.
void getSubTriangles(triangle T, inout triangle array[4])
{
    triangle midTT = returnMidTriangle(T);
    triangle subT[4];
    subT[0].pUp = T.pUp;
    subT[0].pLeft = midTT.pUp;
    subT[0].pRight = midTT.pRight;
    subT[1].pUp = midTT.pUp;
    subT[1].pLeft = T.pLeft;
    subT[1].pRight = midTT.pLeft;
    subT[2].pRight = T.pRight;
    subT[2].pUp = midTT.pRight;
    subT[2].pLeft = midTT.pLeft;
    subT[3] = midTT;

    array = subT;
}

//This prints a triangle onto the screen.
void printTriangle(triangle T)
{   
    Texture = (T.pUp).xyz;
    gl_Position = makeSpherePoint(T.pUp);
    EmitVertex();
    Texture = (T.pLeft).xyz;
    gl_Position = makeSpherePoint(T.pLeft);
    EmitVertex();
    Texture = (T.pRight).xyz;
    gl_Position = makeSpherePoint(T.pRight);
    EmitVertex();
    EndPrimitive(); 
}

片段着色器:

片段着色器很简单。它只接受“纹理”矢量,并使用它来采样地球立方体贴图(使用“纹理”功能)。

这是线框模式视图(没有大地纹理;用于检查球体是否正确渲染):

因此,该球体似乎可以正确渲染,但是现在当我禁用线框架模式并使用地球立方体贴图对球体进行纹理化时,地球的正面和背面纹理会混合在一起:

我不知道为什么会这样。但是,启用GL_CULL_FACE时,地球纹理会呈现完美的重叠状态。

我认为深度缓冲区存在问题,无法检测到其他片段后面的片段。

对此主题的任何帮助将不胜感激。

评论