OpenGL-添加镶嵌控制着色器会产生黑屏



当我将镶嵌控制着色器添加到渲染程序中时,视口变黑。如果没有TSC,顶点和片段着色器可以正常工作。我还检查了编译错误,但没有发生。

顶点着色器:

#version 410 core
layout (location = 0) in vec4 offset;
layout (location = 1) in vec4 color;
out VS_OUT {
    vec4 color;
} vs_out;
void main(void) {
    const vec4 vertices[3] = vec4[3]
    (
        vec4( 0.25, -0.25, 0.5, 1.0),
        vec4(-0.25, -0.25, 0.5, 1.0),
        vec4( 0.25,  0.25, 0.5, 1.0)
    );
    // Add "offset" to our hard-coded vertex position
    gl_Position = vertices[gl_VertexID] + offset;
    // Output the color from input attrib
    vs_out.color = color;
}

细分控制着色器:

#version 410 core
layout (vertices = 3) out;
void main(void) {
    if (gl_InvocationID == 0) {
        gl_TessLevelInner[0] = 5.0;
        gl_TessLevelOuter[0] = 5.0;
        gl_TessLevelOuter[1] = 5.0;
        gl_TessLevelOuter[2] = 5.0;
    }
    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}

细分评估着色器:

#version 410 core
layout (triangles, equal_spacing, cw) in;
void main(void) {
    gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position +
                   gl_TessCoord.y * gl_in[1].gl_Position +
                   gl_TessCoord.z * gl_in[2].gl_Position);
}

片段着色器:

#version 410 core
in VS_OUT {
    vec4 color;
} fs_in;
out vec4 color;
void main(void) {
    color = fs_in.color;
}

我忘记检查着色器链接错误。这就是我得到的:

WARNING: Output of vertex shader '<out VS_OUT.color>' not read by tessellation control shader
ERROR: Input of fragment shader '<in VS_OUT.color>' not written by tessellation evaluation shader

我该怎么解决这个问题?

如果没有其他着色器的代码,很难帮助您。请确保镶嵌评估着色器也是正确的。默认的应该是这样的:

#version 410 core
layout(triangles, equal_spacing, ccw) in;
layout(packed) uniform MatrixBlock
{
    mat4 projmat;
    mat4 viewmat;
} matTransform;
void main ()
{
    vec4 pos = gl_TessCoord.x * gl_in[0].gl_Position
             + gl_TessCoord.y * gl_in[1].gl_Position
             + gl_TessCoord.z * gl_in[2].gl_Position;
    gl_Position = matTransform.projmat * matTransform.viewmat * pos;
}

重要的部分是使用重心坐标在面片三角形上进行插值。此外,如果变换是在顶点着色器而不是tess-eval着色器中完成的,则可能也会产生奇怪的结果。

编辑:

既然添加了镶嵌阶段,就无法将不同的数据从顶点着色器传递到片段着色器。事实上,它们是原始面片三角形中的新三角形,所以你也必须为所有这些新三角形设置颜色。实际上,当使用镶嵌阶段时,顶点着色器和tess控件通常会将顶点输入转发到tess-eval着色器。

所以你的tess控制着色器应该像:

#version 410 core
layout (vertices = 3) out;
in VS_OUT { vec4 color; } tcs_in[];   /* new */
out TCS_OUT { vec4 color; } tcs_out[];  /* new */
void main(void) {
    if (gl_InvocationID == 0) {
        gl_TessLevelInner[0] = 5.0;
        gl_TessLevelOuter[0] = 5.0;
        gl_TessLevelOuter[1] = 5.0;
        gl_TessLevelOuter[2] = 5.0;
    }
    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
    tcs_out[gl_InvocationID].color = tcs_in[gl_InvocationID].color; /* forward the data */
}

并且你的tess-eval着色器还必须插值颜色:

#version 410 core
layout (triangles, equal_spacing, cw) in;
in TCS_OUT { vec4 color; } tes_in[];  /* new */
out TES_OUT { vec4 color; } tes_out;  /* new */
void main(void) {
    tes_out.color = (gl_TessCoord.x * tes_in[0].color + /* Interpolation */
                     gl_TessCoord.y * tes_in[1].color +
                     gl_TessCoord.z * tes_in[2].color );
    gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position +
                   gl_TessCoord.y * gl_in[1].gl_Position +
                   gl_TessCoord.z * gl_in[2].gl_Position);
}

当然,在片段着色器中,现在有了TES_OUT而不是VS_OUT

我知道这个问题已经两年了,但我这可能会帮助未来遇到同样问题并找到这个问题的人。


经过几个小时的努力,我终于解决了这个问题。顶点着色器似乎没有写入细分控制着色器的gl_in[].gl_Position输入。我怀疑这一定是一个驱动程序错误(可能在英伟达驱动程序中?),因为我想不出任何原因不应该这样做。

解决方案:

不依赖细分控制着色器的gl_in[].gl_Position输入,只需在自定义输出/输入中自行传递即可。

这可以通过(粗略地)向各个着色器添加以下行来完成:

// vertex shader
// ...
out vec4 vVertexOut;
void main() {
    // ...
    vVertexOut = uMVPMatrix * inVertex; // output your transformed vertex
}

// tesselation control shader
// ...
in vec4 vVertexOut[];
out vec4 tVertexOut[];
void main() {
    // ...
    tVertexOut[gl_InvocationID] = vVertexOut[gl_InvocationID];
}

// tesselation evaluation shader
// ...
in vec4 tVertexOut[];
void main() {
    // ...
    gl_Position = (tVertexOut[0] * gl_TessCoord[0]) + (tVertexOut[1] * gl_TessCoord[1]) + (tVertexOut[2] * gl_TessCoord[2]);
}

相关内容

  • 没有找到相关文章