0

私はシェーダーで少し経験していますが、この奇妙なコンパイルエラーが発生し続け、私を夢中にさせています!

次のピクセル シェーダー コード スニペット:

            DirectionVector = normalize(f3LightPosition[i] - PixelPos);
            LightVec = PixelNormal - DirectionVector;

            // Get the light strenght factor
            LightStrFactor = float(abs((LightVec.x + LightVec.y + LightVec.z) / 3.0f));

            // TEST!!!
            LightStrFactor = 1.0f;

            // Add this light to the total light on this pixel
            LightVal += f4Light[i] * LightStrFactor;

完全に機能しますが、「LightStrFactor = 1.0f;」を削除するとすぐに つまり、「LightStrFactor」の値を上記の計算の結果にすると、シェーダーのコンパイルに失敗します。

LightStrFactor は float です LightVal & f4Light[i] は float4 です 残りはすべて float3 です。

私の質問は、なぜそれがコンパイルされないのかということに加えて、なぜDXコンパイラはfloatの値を気にするのですか? 私の値が間違っていても、それは実行時ではないでしょうか? シェーダーのコンパイル コードは次のとおりです。

/* Compile the bitch */
if (FAILED(D3DXCompileShaderFromFile(fileName, NULL, NULL, "PS_MAIN", "ps_2_0", 0, &this->m_pCode, NULL, &this->m_constantTable)))
    GraphicException("Failed to compile pixel shader!");  // <-- gets here :(

if (FAILED(g_D3dDevice->CreatePixelShader( (DWORD*)this->m_pCode->GetBufferPointer(), &this->m_hPixelShader )))
    GraphicException("Failed to create pixel shader!");

this->m_fLoaded = true;

どんな助けでも大歓迎ですありがとう!!! :]

4

3 に答える 3

0

ピクセル シェーダーは C++ スタイルのキャストをサポートしていません。あなたの例ではfloat(... です)。これは完全に冗長なので取り除くだけでよいのですが、キャストが必要な場合(float)は C の as を使用します。

于 2010-03-22T19:29:40.430 に答える
0

シェーダー スニペットから、多数のライトを反復処理して、それらの寄与を蓄積しているように見えます。

私の推測では、コンパイラが実際のライト シェーディング計算でループをアンロールすると、コンパイルされたシェーダーは ps_2_0 プロファイルがサポートするよりも多くの算術命令スロットを使用します (最大 64 命令)。

計算を LightStrFactor=1 に置き換えると、コンパイラはそれより前の 3 つのコード行を完全に最適化します。その結果、テスト シェーダーが大幅に短くなり、割り当てられた 64 命令内に収まります。

アプリケーション ハードウェア ターゲットで可能であれば、シェーダー プロファイルのバージョンを上げるだけで、シェーダーがより多くの命令スロットを使用し、エラーなしでコンパイルできるようになります。ps_3_0 / ps_2_a / ps_2_b のいずれかでシェーダーをコンパイルできる必要があります。(2_a/b プロファイルはちょっとひどいですが、正式にサポートされている、ベース 2_0 プロファイルに対する NV/ATI 拡張です)

(別の返信で述べたように、時間をかけてコンパイル エラーをキャプチャして出力することは、十分に価値のあることです。)

于 2010-03-25T10:30:03.710 に答える
0

シェーダーはコンパイル時に最適化されることを忘れないでください。これが、値をハードコーディングしても失敗しない理由かもしれません。

値を方程式に割り当てた直後に値をハードコーディングすると、方程式全体が最適化され、最終的な割り当てのみが除外されます。

于 2010-03-22T18:28:04.137 に答える