2

基本的に、(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. フレームごとに1回、ZBufferを黒、透明、または白にクリアすると、すべて同じ効果があります(これは、BeginSceneが呼び出される直前です)。

Direct3DWrapper.ClearDevice(SlimDX.Direct3D9.ClearFlags.ZBuffer、Color.Transparent、0);

  1. 他のすべてのスプライトはZ=1で描画され、ZBufferは無効になっています。

device.SetRenderState(RenderState.ZEnable、ZBufferType.DontUseZBuffer);

  1. フォースフィールドスプライトはZ=2で描画され、ZBufferが有効で、ZWriteが有効で、ZFuncがLessとして描画されます。

device.SetRenderState(RenderState.ZEnable、ZBufferType.UseZBuffer); device.SetRenderState(RenderState.ZWriteEnable、true); device.SetRenderState(RenderState.ZFunc、Compare.Less);

  1. 私が遭遇した黒い境界線のアーティファクトを防ぐために、この時点で次のフラグも設定されています。

device.SetRenderState(RenderState.AlphaTestEnable、true); device.SetRenderState(RenderState.AlphaFunc、Compare.GreaterEqual); device.SetRenderState(RenderState.AlphaRef、55);

私が使用していた特定のソース画像に設定されたアルファレベルのため、AlphaRefは55であることに注意してください。ソース画像のアルファ値が高い場合は、AlphaRefも高くする必要があります。

4

3 に答える 3

1

両方の力場が同じ色であるため、モックアップから何を達成しようとしているのかを正確に判断するのは困難です。色をブレンドしてアルファをキャップしますか?色の1つを取るだけですか?

上記の説明に基づいて、関連するすべてのレンダリング状態を設定しているかどうかは明確ではありません。

D3DRS_ALPHABLENDENABLE = TRUE(デフォルト:FALSE)

D3DRS_BLENDOP = D3DBLENDOP_MAX(デフォルト:D3DBLENDOP_ADD)

D3DRS_SRCBLEND = D3DBLEND_ONE(デフォルト:D3DBLEND_ONE)

D3DRS_DESTBLEND = D3DBLEND_ONE(デフォルト:D3DBLEND_ZERO)

最初の2つを設定しているように聞こえますが、最後の2つはどうですか?

于 2009-08-26T02:06:40.337 に答える
1

アルファチャネル用に2つの画像をブレンドするときに使用するD3DBLENDOPを指定できます。現在使用しているようです。D3DBLENDOP_ADDこれをに切り替えてみてくださいD3DBLENDOP_MAX。「最も不透明な」画像の不透明度が使用されるだけです。

于 2009-08-20T17:24:12.680 に答える
1

私が知ることができる最善のことは、力場はオブジェクト全体であるということです。Zバッファリングを有効にして、前から後ろの順序で最後にレンダリングしてみませんか。それはあなたが求めている効果をあなたに与えるでしょう。

つまり、設定をブレンドしないことが問題になります。

編集:それでは、render-to-textureを使用できますか?そうすれば、フォトショップでやったことを簡単に行うことができます。それらをすべて一緒にテクスチャにレンダリングしてから、テクスチャを画面上にブレンドして戻します。

Edit2:どうですか

ALPHATESTENABLE  = TRUE;
ALPHAFUNC = LESS

ALPHABLENDENABLE = TRUE;
SRCBLEND = SRCALPHA;
DESTBLEND = INVSRCALPHA;

SEPERATEALPHABLENDENABLE = TRUE;
SRCBLENDALPHA = ONE;
DESTBLENDALPHA = ZERO;

各フレームのフレームバッファでアルファが0xffにクリアされていることを確認する必要があります。次に、標準のアルファブレンドを実行します。アルファ値をバックバッファに直接渡します。ただし、これがアルファテストの出番です。最終的なアルファ値をバックバッファの値に対してテストします。バックバッファの値よりも小さい場合、そのピクセルはまだブレンドされておらず、フレームバッファに配置されます。等しい(またはそれ以上)場合は、すでにブレンドされており、アルファ値は破棄されます。

そうは言っても...Zバッファを使用すると、RAMの負荷がかかりますが、パイプラインのはるかに早い段階でピクセルを破棄できるため、全体的に高速になります。すべてのシールドが特定のZ平面に書き込まれるだけでよいので、前に提案した地獄を通過する必要さえありません。受け取ったZ値がすでに存在する値よりも小さい場合は、それ以上の場合はレンダリングされ、幸いなことに、ブレンド計算が実行される前に破棄されます。

そうは言っても...とにかくZバッファを必要とするステンシルバッファを使用してそれを行うこともできます。

とにかく...それらの方法の1つが何らかの助けになることを願っています。

Edit3:エッジの周りに何らかの形のフェザリングを使用して力場をレンダリングしますか?ほとんどの場合、エッジはアルファがわずかにフェードオフし、「わずかにアルファ」のピクセルがzバッファに書き込まれるため、後続の描画で上書きされないことが原因である可能性があります。

次の設定を試してください

ALPHATESTENABLE = TRUE
ALPHAFUNC = GREATEREQUAL // if this doesn't work try less .. i may be being a retard
ALPHAREF = 255

エッジの周りのフェザリングを微調整するには、alpharefを調整しますが、上記のように維持する必要があると思います。

于 2009-08-26T06:47:09.053 に答える