Directx和; HLSL - 正常重新计算

时间:2012-07-21 04:57:48

标签: c++ game-engine hlsl directx-9

我正在使用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()
};

我知道如何访问邻接数据和顶点缓冲区但是我不知道使用什么方法来正确地将顶点及其法线与面相关联...任何帮助都将非常感激。谢谢!

1 个答案:

答案 0 :(得分:2)

更新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;
}