我正在使用HLSL和DirectX9。我正在尝试重新计算网格的法线,以便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;
}

关于c++ - Direct X和HLSL-正常重新计算,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11589599/

10-09 13:26