2

HLSL と DirectX 9 を使用しています。メッシュの変換の結果として更新された法線を HLSL が受け取るように、メッシュの法線を再計算しようとしています。これを行うのに最適な方法は何ですか...また...頂点宣言としてFVF_NORMALを使用していないため、D3DXComputeNormalsは機能しません...頂点フォーマットを次のように宣言します。

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 に答える