【问题标题】:Directional per-face lighting using Geometry Shader?使用几何着色器的定向逐面照明?
【发布时间】:2015-03-08 22:04:00
【问题描述】:

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

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

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

以下代码有些作用,但会改变相机/光线方向的角度:

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();
}

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

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

【问题讨论】:

  • 这不是在做“逐顶点”光照。这是使用顶点复制进行“每面”照明。这可能会很慢,因为您在 GS 中进行顶点复制,尽管您至少产生与输入相同数量的输出,这意味着您不会受到最坏情况下的 GS 性能的影响。
  • @ChuckWalbourn 我修正了标题,如果您知道任何与顶点顺序无关的照明选项,我想听听它们:)

标签: directx hlsl normals geometry-shader


【解决方案1】:

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

【讨论】:

  • “但是,剪辑空间不适合照明计算” 这对我有用,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多