Opengl 在几何体着色器中计算细分后的逐顶点法线

Opengl 在几何体着色器中计算细分后的逐顶点法线,opengl,glsl,geometry-shader,Opengl,Glsl,Geometry Shader,我已经成功地使镶嵌控制和求值着色器正常工作,但我的场景的照明仍然是块状的,因为我一直在计算每(三角形)面法线,而不是每顶点。现在我正在使用细分,似乎有必要在tess eval或geometry着色器中为新细分的顶点计算新的法线顶点 为了获得平滑的逐顶点法线,我需要计算共享所讨论顶点的每个三角形的逐面法线,然后计算这些面法线的加权平均值。但我不知道如何在tess eval或geometry着色器中获得所有这些三角形面。用于几何体着色器的中的布局(三角形\u邻接)选项看起来很有希望,但关于如何使用它

我已经成功地使镶嵌控制和求值着色器正常工作,但我的场景的照明仍然是块状的,因为我一直在计算每(三角形)面法线,而不是每顶点。现在我正在使用细分,似乎有必要在tess eval或geometry着色器中为新细分的顶点计算新的法线顶点

为了获得平滑的逐顶点法线,我需要计算共享所讨论顶点的每个三角形的逐面法线,然后计算这些面法线的加权平均值。但我不知道如何在tess eval或geometry着色器中获得所有这些三角形面。用于几何体着色器的中的
布局(三角形\u邻接)选项看起来很有希望,但关于如何使用它的信息不多

不使用法线/凹凸贴图的情况下,是否可以在GPU上计算逐顶点平滑法线?最终目标是获得平滑的逐顶点照明,从而受益于增加的细分细节级别

以下是我的细分控制和求值着色器:

// control
#version 400

layout (vertices = 3) out;

in vec3 vPosition[];
out vec3 tcPosition[];

const float tessLevelInner = 1.0;
const float tessLevelOuter = 1.0;

void main()
{
    tcPosition[gl_InvocationID] = vPosition[gl_InvocationID];
    if (gl_InvocationID == 0) {
        gl_TessLevelInner[0] = tessLevelInner;
        gl_TessLevelOuter[0] = tessLevelOuter;
        gl_TessLevelOuter[1] = tessLevelOuter;
        gl_TessLevelOuter[2] = tessLevelOuter;
    }
}

// eval
#version 400

layout (triangles, equal_spacing, cw) in;
uniform mat4 uProj;
uniform mat4 uModelView;

in vec3 tcPosition[];
out vec3 tePosition;

void main()
{
    vec3 p0 = gl_TessCoord.x * tcPosition[0];
    vec3 p1 = gl_TessCoord.y * tcPosition[1];
    vec3 p2 = gl_TessCoord.z * tcPosition[2];

    tePosition = p0 + p1 + p2;
    gl_Position = uProj * uModelView * vec4(tePosition, 1);
}

“为了获得平滑的逐顶点法线,我需要计算共享相关顶点的每个三角形的逐面法线,然后计算这些面法线的加权平均值。”否。如果使用细分,细分算法通常能够计算法线,正如它提供了计算位置的能力一样,我正在以一种非常标准的方式在tess控件和eval着色器中进行tesselation。你能详细介绍一下细分算法是如何计算法线的吗?这方面的“标准方式”是什么?一般来说,镶嵌是完全任意的。如何计算法线完全取决于您的细分算法。现在,我没有对动态细分级别做任何花哨的事情,我已经发布了我的tess着色器代码,顶点着色器非常简单。并且没有可用的泛化?我在上面提出的使用几何体着色器的方法有什么优点吗?如果你能解释一下在这种特殊情况下如何计算法线,以及为什么它不适用于不同的细分算法,这可能会帮助我更好地理解这个问题。