2012-07-21 25 views
2

我正在使用HLSL和DirectX 9.我正在尝试重新计算网格的法线,以便HLSL通过变换网格接收更新的法线。用什么方法最好是做这个...也... ... D3DXComputeNormals不会为我工作,因为我不使用FVF_NORMAL作为一个顶点声明......我宣布类似的顶点格式,以便:Direct X&HLSL - 正常重新计算

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

我知道如何访问邻接数据和顶点缓冲区,但我不知道要使用什么方法才能正确地将顶点及其正常与脸相关联......任何帮助将不胜感激。谢谢!

+0

如果我理解正确的话,你就与法线网格,而当你变换(如旋转)的网格,你想,让他们在正确的方向指向更新法线? – Hannesh 2012-07-21 08:20:50

回答

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