基本的に、(DirectXで)私がやりたいのは、2つの部分的に透明な画像を取得し、それらをブレンドすることです。これは、両方がオーバーラップしているなどとして表示される限り、デフォルトのブレンドで正常に機能します。ただし、問題は、2つが交差する場所で不透明度が著しく上昇することです。これにより、より多くのスプライトがオーバーラップするため、問題が増加します。私がやりたいのは、どのようにオーバーラップするかに関係なく、ブレンドされるこれらすべてのスプライトのグローバルな不透明度を維持することを除いて、ブレンドを同じに保つことです。
これにはレンダリング設定があるようです(これらのスプライトはすべてスプライトバッチに単独で含まれているため、その部分が簡単になります)が、そうである場合はわかりません。今、私は暗闇の中で撮影しているようなもので、色々なことを試しましたが、どれもまったく正しく見えませんでした。おそらくD3DBLENDOPのある種のバリアントが必要なことはわかっていますが、実際に必要な設定の種類がわかりません(私は多くのことを試しましたが、この段階ではすべて推測しています)。
これは、標準のブレンディングで実際に起こっていることのスクリーンショットです(私が得ることができる最高のものです):http ://arcengames.com/share/FFActual.pngこれは、ブレンディングをどのように変えたいかをモックアップしたスクリーンショットです。 out(フォースフィールドはPhotoshopの同じレイヤーに追加され、共有アルファ値が与えられました):http ://arcengames.com/share/FFMockup.png
これが私がPhotoshopで行った方法です。1。2つの画像を取得し、すべての透明度を削除します(完全に透明なピクセルを除く)。2.それらを1つのレイヤーに結合します。このレイヤーは、色をブレンドしますが、部分的なアルファはまったくありません。3.次に、そのレイヤーのグローバル透明度を(たとえば)40%に設定します。
その結果、色の点でブレンドされたように見えますが、重なり合った部分の不透明度は増加しません。
更新:さて、Zバッファの使用を提案してくれた以下のGozに感謝します。それはうまくいきます!全体として、ブレンドは完璧で、まさに私が望むものです。残っている唯一の問題は?その新しい方法を使用すると、最後にレンダリングされるフォースフィールドイメージのエッジの周りに巨大なアーティファクトがあります。これを参照してください: http ://www.arcengames.com/share/FFZBuffer.png
更新:以下はC#(SlimDX)の最終的な解決策です
- フレームごとに1回、ZBufferを黒、透明、または白にクリアすると、すべて同じ効果があります(これは、BeginSceneが呼び出される直前です)。
Direct3DWrapper.ClearDevice(SlimDX.Direct3D9.ClearFlags.ZBuffer、Color.Transparent、0);
- 他のすべてのスプライトはZ=1で描画され、ZBufferは無効になっています。
device.SetRenderState(RenderState.ZEnable、ZBufferType.DontUseZBuffer);
- フォースフィールドスプライトはZ=2で描画され、ZBufferが有効で、ZWriteが有効で、ZFuncがLessとして描画されます。
device.SetRenderState(RenderState.ZEnable、ZBufferType.UseZBuffer); device.SetRenderState(RenderState.ZWriteEnable、true); device.SetRenderState(RenderState.ZFunc、Compare.Less);
- 私が遭遇した黒い境界線のアーティファクトを防ぐために、この時点で次のフラグも設定されています。
device.SetRenderState(RenderState.AlphaTestEnable、true); device.SetRenderState(RenderState.AlphaFunc、Compare.GreaterEqual); device.SetRenderState(RenderState.AlphaRef、55);
私が使用していた特定のソース画像に設定されたアルファレベルのため、AlphaRefは55であることに注意してください。ソース画像のアルファ値が高い場合は、AlphaRefも高くする必要があります。