使用Geometry Shader定向每面照明?

时间:2015-03-08 22:04:00

标签: directx hlsl normals geometry-shader

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

在几何着色器中计算的法线在屏幕空间中,但是从我做过的一些测试中它们是正确的。

我可以在世界空间中提供光的方向,或者乘以视图/投影/转置/反转矩阵。

下面的代码有些可行,但在相机/光线方向角度上有所改变:

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之前进行标准化。

在几何着色器中正确计算光线所需的数学是什么?

1 个答案:

答案 0 :(得分:0)

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