1

3D ビューの背景として天球を描いています。時折、ビューをナビゲートしているときに、視覚的な不具合が発生することがあります。

青空の真ん中にある黒いポリゴンまたはポリゴンの欠落

グリッチの例: レンダリングが画面上にフラグメントを配置していないように見える黒い形状

  • 黒は、各フレームの開始時にデバイスがクリアされる色です。
  • 黒い領域の形状は毎回異なり、目に見えるほど多くのポリゴンになっている場合があります。それらは常に、通常は画面の中心近くにある共通点を中心にしています。
  • ナビゲーション (目の位置と外観) を変更せずに再描画してもグリッチは消えません。つまり、特定のナビゲーションに依存しているように見えます。
  • 航法を変えた瞬間、微量でも消えて空がベタベタ描く。絵の大部分は正しいです。最終的に動き回ると、別の不具合を発見します。
  • 球の半径を変更しても (たとえば、近距離/遠距離の 0.9 に)、グリッチが除去されないようです。
  • Z バッファの書き込みまたはエフェクト テクニックの Z テストを変更しても違いはありません
  • DX デバッグ出力はありません (デバッグ バージョンのランタイム、最大検証、およびシェーダー デバッグを有効にして実行した場合)。

これらの不具合の原因は何ですか?

SM3 にコンパイルされたシェーダーである Direct3D9 (2010 年 6 月 SDK) を使用していますが、Windows 7 および XP の ATI カードおよび VMWare Fusion 仮想カードでグリッチが確認されています。

サンプルコード

空は球体として描画されています (エラーチェックなどにより、以下のコードが削除されました)。

作成するには

const float fRadius = GetScene().GetFarPlane() - GetScene().GetNearPlane()*2;
D3DXCreateSphere(GetScene().GetDevicePtr(), fRadius, 64, 64, &m_poSphere, 0);

半径を変更しても、グリッチの存在には影響しないようです。

頂点シェーダー

OutputVS ColorVS(float3 posL : POSITION0, float4 c : COLOR0) {
   OutputVS outVS = (OutputVS)0;
   // Center around the eye
   posL += g_vecEyePos; 
   // Transform to homogeneous clip space.
   outVS.posH = mul(float4(posL, 1.0f), g_mWorldViewProj).xyzw; // Always on the far plane

ピクセル シェーダー

単色を出力するものでもグリッチが発生します。

float4 ColorPS(float altitude : COLOR0) : COLOR {
   return float4(1.0, 0.0, 0.0, 1.0);

単色のピクセル シェーダーを使用した同じ画像

PS が問題の原因ではないことを確認するために、無地のピクセル シェーダーを使用した同じ画像

技術

technique BackgroundTech {
    pass P0     {
        // Specify the vertex and pixel shader associated with this pass.
        vertexShader = compile vs_3_0 ColorVS();
        pixelShader  = compile ps_3_0 ColorPS();

        // sky is visible from inside - cull mode is inverted (clockwise)
        CullMode = CW;
    }
}

など、深度に影響する状態設定を追加してみましたZWriteEnabled = false。どれも違いはありませんでした。

4

1 に答える 1

1

この問題は、ファー プレーン クリッピングが原因であることは間違いありません。球の半径を少し変更しても問題が解決しない場合は、球の位置が間違っている可能性があります...

定数を適切に初期化していることを確認してくださいg_vecEyePos(DirectX SetShaderConstant 関数のいずれかでスペルを間違えた可能性があります)。

また、 のワールド マトリックスに目の位置への変換を含めた場合、頂点が目の位置の 2 倍移動するため、VS でg_mWorldViewProj行うべきではありません。posL += g_vecEyePos;

つまり、次のオプションのいずれかを選択する必要があります。

  1. g_mWorldViewProj = mCamView * mCamProj;posL += g_vecEyePos;

  2. g_mWorldViewProj = MatrixTranslation(g_vecEyePos) * mCamView * mCamProj;

于 2012-08-21T22:22:40.493 に答える