着色器翻转面

Shader Flipping Faces

我正在尝试使用 OpenGL 和 C++ 构建渲染引擎。但似乎无法解决这个问题。同一模型使用不同的着色器渲染了 5 次不同的时间,在 5 个着色器中的 4 个中,背面剔除工作正常。然而,在曲面细分着色器中,情况并非如此。任何向外的面孔都是不可见的,因此您可以直接看到后面的面孔。有谁知道为什么这个着色器会翻转面部?

顶点着色器

void main()
{
    worldVertexPosition_cs = (transformationMatrix * vec4(position_vs, 1.0)).xyz;
    worldTextureCoords_cs = textureCoords_vs;
    worldNormal_cs = mat3(transpose(inverse(transformationMatrix))) * normal_vs;
}

控制着色器

float getTessLevel(float distance0, float distance1)
{
    float avgDistance = (distance0 + distance1) / 2.0;
    avgDistance = (100 - avgDistance) / 20;
    if (avgDistance < 1) {
        avgDistance = 1;
    }
    return avgDistance;
}

void main()
{
    worldTextureCoords_es[gl_InvocationID] = worldTextureCoords_cs[gl_InvocationID];
    worldNormal_es[gl_InvocationID] = worldNormal_cs[gl_InvocationID];
    worldVertexPosition_es[gl_InvocationID] = worldVertexPosition_cs[gl_InvocationID];

    float eyeToVertexDistance0 = distance(eyePos, worldVertexPosition_es[0]);
    float eyeToVertexDistance1 = distance(eyePos, worldVertexPosition_es[1]);
    float eyeToVertexDistance2 = distance(eyePos, worldVertexPosition_es[2]);

    gl_TessLevelOuter[0] = getTessLevel(eyeToVertexDistance1, eyeToVertexDistance2);
    gl_TessLevelOuter[1] = getTessLevel(eyeToVertexDistance2, eyeToVertexDistance0);
    gl_TessLevelOuter[2] = getTessLevel(eyeToVertexDistance0, eyeToVertexDistance1);
    gl_TessLevelInner[0] = gl_TessLevelOuter[2];
}

评估着色器

vec2 interpolate2D(vec2 v0, vec2 v1, vec2 v2)
{
    return vec2(gl_TessCoord.x) * v0 + vec2(gl_TessCoord.y) * v1 + vec2(gl_TessCoord.z) * v2;
}

vec3 interpolate3D(vec3 v0, vec3 v1, vec3 v2)
{
    return vec3(gl_TessCoord.x) * v0 + vec3(gl_TessCoord.y) * v1 + vec3(gl_TessCoord.z) * v2;
}

void main()
{
    worldTextureCoords_fs = interpolate2D(worldTextureCoords_es[0], worldTextureCoords_es[1],         worldTextureCoords_es[2]);
    worldNormal_fs = interpolate3D(worldNormal_es[0], worldNormal_es[1], worldNormal_es[2]);
    worldNormal_fs = normalize(worldNormal_fs);
    worldVertexPosition_fs = interpolate3D(worldVertexPosition_es[0], worldVertexPosition_es[1],     worldVertexPosition_es[2]);

    float displacement = texture(texture_displacement0, worldTextureCoords_fs.xy).x;
    worldVertexPosition_fs += worldNormal_fs * (displacement / 1.0f);

    gl_Position = projectionMatrix * viewMatrix * vec4(worldVertexPosition_fs.xyz, 1.0);
}

片段着色器

void main()
{
    vec3 unitNormal = normalize(worldNormal_fs);
    vec3 unitLightVector = normalize(lightPosition - worldVertexPosition_fs);

    float dotResult = dot(unitNormal, unitLightVector);
    float brightness = max(dotResult, blackPoint);
    vec3 diffuse = brightness * lightColor;

    FragColor = vec4(diffuse, 1.0) * texture(texture_diffuse0, worldTextureCoords_fs);
    FragColor.rgb = pow(FragColor.rgb, vec3(1.0/gamma));
}

Tessellation Evaluation Shader 中,您必须定义生成的三角形的缠绕顺序。
这是通过 cwccw 参数完成的。默认为 ccw.

要么生成顺时针图元:

layout(triangles, cw) in;

或生成逆时针图元:

layout(triangles, ccw) in;