Direct X & HLSL - Normal ReComputing

Direct X & HLSL - Normal ReCalculation

本文关键字:Normal ReComputing HLSL Direct      更新时间:2023-10-16

我使用的是HLSL和DirectX 9。我正在尝试重新计算网格的法线,以便HLSL在变换网格时接收更新的法线。做这件事最好用什么方法。。。而且D3DXComputeNormals将不适用于我,因为我不使用FVF_NORMAL作为顶点声明。。。我这样声明顶点格式:

const D3DVERTEXELEMENT9 dec[4] =
{
  {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,0},
  {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,  0},
  {0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,0},
  D3DDECL_END()
};

我知道如何访问邻接数据和顶点缓冲区,但我不确定该使用什么方法来正确地将顶点及其法线与面关联。。。如有任何帮助,我们将不胜感激。谢谢

更新CPU上的法线并在每帧将其发送到GPU不是一个好主意。那会毁了演出。真正应该做的是计算顶点着色器中的变换法线,就像计算位置一样。HLSL代码如下所示:

float4x4 mWorldView; // World * View
float4x4 mWorldViewProj; // World * View * Proj
struct VS_OUTPUT
{
    float4 position : POSITION;
    float2 tex : TEXCOORD0;
    float3 normalVS : TEXCOORD1; // view-space normal
};
// Vertex Shader
VS_OUTPUT VS(float3 position : POSITION,
             float3 normal   : NORMAL,
             float2 tex      : TEXCOORD0)
{
    VS_OUTPUT out;
    // transform the position
    out.position = mul(float4(position, 1), mWorldViewProj);
    // pass the texture coordinates to the pixel shader
    out.tex = tex;
    // calculate the transformed normal
    float3 n = mul(normal, (float3x3)mWorldView); // calculate view-space normal
    // and use it for vertex lighting
    // ... some shading calculations ...
    // or pass it to the pixel shader and perform per-pixel lighting
    out.normalVS = n;
    // output
    return out;
}