使用几何着色器的定向单面照明?

Directional per-face lighting using Geometry Shader?

由于限制,我必须在我的几何着色器中计算顶点法线。由于这个限制,法线是每个面而不是在顶点上的面之间插值,这意味着每个像素的定向照明只是一种浪费。因为法线只能从几何着色器开始知道,所以我无法在顶点着色器中进行任何光照计算。

在几何着色器中计算的法线在屏幕上space,但根据我所做的一些测试,它们是正确的。

我可以提供world-space或乘以view/projection/transposed/inverted矩阵的光的方向。

以下代码部分有效,但在 camera/lightdirection 角度发生了变化:

void FlipFaceGS(triangle PS_IN input[3], inout TriangleStream<PS_IN> OutputStream)
{
    PS_IN v1 = input[0];
    PS_IN v2 = input[1];
    PS_IN v3 = input[2];

    float3 faceEdgeA = v2.pos - v1.pos;
    float3 faceEdgeB = v3.pos - v1.pos;
    float3 faceNormal = normalize(cross(faceEdgeA, faceEdgeB));

    v1.norm = faceNormal;
    v2.norm = faceNormal;
    v3.norm = faceNormal;

    float4 newColor = (v1.color * Light1Color * max(0, dot(v1.norm, Light1Direction)));
    newColor.a = v1.color.a;//we don't want to affect the alpha levels

    v1.color = newColor;
    v2.color = newColor;
    v3.color = newColor;

    OutputStream.Append(v1);
    OutputStream.Append(v2);
    OutputStream.Append(v3);
    OutputStream.RestartStrip();
}

在上面的示例中,lightdirection 乘以相机的 ViewProjection 矩阵并在发送到 GPU 之前进行归一化。

在几何着色器中正确计算光线需要什么数学知识?

我假设您的输入顶点位置已经转换为剪辑 space。然后,至少你在计算相同 space 中的光照。但是,clip space 不适合光照计算,因为透视变换不保持角度。在 world 或 view space 中进行计算。在任何一种情况下,您还必须将相应 space 中的顶点位置传递给几何着色器。如果不需要,不要将法线传递给像素着色器。