2

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

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

4

1 回答 1

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;
}
于 2012-07-30T16:42:30.670 回答