私は簡単なことをしたいと思います: アルファ シャネル ブレンディングを使用して、2D テクスチャを 2D レンダー ターゲットにレンダリングします。
だから私は自分のレンダーターガーを作成します:
renderTarget = new RenderTarget2D(m_graphicsDevice, 200, 200);
次に、テクスチャを作成します。
texture = new Texture2D(_device, 1, 1, false, SurfaceFormat.Color);
Color clr = Color.Red;
// set half transparency on my texture
clr.A = 128;
Color[] bitmap = new Color[1] {clr};
texture.SetData(bitmap);
次に、レンダー ターゲットを白くクリアし、レンダー ターゲットにテクスチャを 2 回描画します。適切なスケールで、色とアルファ シャネルの乗法演算を使用します。
graphicsDevice.SetRenderTarget(renderTarget);
graphicsDevice.Clear(Color.White);
BlendState myState = new BlendState();
// multiplicative blending on color
myState.ColorSourceBlend = Blend.Zero;
myState.ColorDestinationBlend = Blend.SourceColor;
// multiplicative blending on alpha
myState.AlphaSourceBlend = Blend.Zero;
myState.AlphaDestinationBlend = Blend.SourceAlpha;
spriteBatch.Begin(SpriteSortMode.Immediate, myState);
// draw my texture twice, with an overlaping part
spriteBatch.Draw(texture, new Vector2(0, 0), null, Color.White, 0, Vector2.Zero, 100, SpriteEffects.None, 0);
spriteBatch.Draw(texture, new Vector2(50, 50), null, Color.White, 0, Vector2.Zero, 100, SpriteEffects.None, 0);
spriteBatch.End();
graphicsDevice.SetRenderTarget(null);
このレンダー ターゲットを画面上に描画します。背景は緑色で、レンダーステートは nonPremultiplied で、テクスチャのアルファ値が透明度として適用されます。
graphicsDevice.Clear(Color.Green);
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied);
spriteBatch.Draw(renderTarget, Vector2.zero, Color.White);
spriteBatch.End();
結果は期待どおりです:
レンダー ターゲットで、1 つのテクスチャのみに属するピクセルの場合:
- 赤のシャネル = テクスチャの赤のシャネル (1) * レンダー ターゲットの赤のシャネル (1) = 1
- 緑と青のシャネル = テクスチャ シャネル (0) * レンダー ターゲット シャネル = 0
- アルファ シャネル = テクスチャ アルファ (0.5) * レンダー ターゲット アルファ (1) = 0.5
- 緑の背景の上に描画されたこのテクスチャは、アルファ透明度が 0.5 (1/2 赤 + 1/2 緑) に設定されているため、茶色になります。
レンダー ターゲット内、オーバーラップ ピクセル用 (上記の計算が 2 回適用される)
- 赤のシャネル = テクスチャの赤のシャネル (1) * テクスチャの赤のシャネル (1) * レンダー ターゲットの赤のシャネル (1) = 1
- 緑と青のシャネル = テクスチャ シャネル (0) * テクスチャ シャネル (0) * レンダー ターゲット シャネル = 0
- アルファ シャネル = テクスチャ アルファ (0.5) * テクスチャ アルファ (0.5) * レンダー ターゲット アルファ (1) = 0.25
- 緑の背景の上に描画されたこのテクスチャは、アルファ値 0.25 (1/4 赤 + 3/4 緑) のおかげでほぼ緑の色になります。
ここで、renderstate を変更して、テクスチャのアルファ シャネルを適用し、色の乗算を行わないようにすると、次のようになります。
BlendState myState = new BlendState();
// texture color is ignored, dest color remain unchanged
myState.ColorSourceBlend = Blend.Zero;
myState.ColorDestinationBlend = Blend.One;
// alpha chanel are still multiplied
myState.AlphaSourceBlend = Blend.Zero;
myState.AlphaDestinationBlend = Blend.SourceAlpha;
私が得るべきものは:
レンダー ターゲットで、1 つのテクスチャのみに属するピクセルの場合:
- 赤のシャネル = 0 * テクスチャの赤のシャネル (1) + 1 * レンダー ターゲットの赤のシャネル (1) = 1
- 緑と青のシャネル = 0 * テクスチャ シャネル (0) + 1 * レンダー ターゲット シャネル (1) = 1
- アルファ シャネル = テクスチャ アルファ (0.5) * レンダー ターゲット アルファ (1) = 0.5
- 緑色の背景の上に描画されたこのテクスチャは、明るい緑色 (1/2 白 + 1/2 緑) になります。
レンダー ターゲット内、オーバーラップ ピクセル用 (上記の計算が 2 回適用される)
- 赤いシャネル = 1
- 緑と青のシャネル = 1
- アルファ シャネル = テクスチャ アルファ (0.5) * テクスチャ アルファ (0.5) * レンダー ターゲット アルファ (1) = 0.25
- 緑の背景の上に描画されたこのテクスチャは、より強い緑になります (0.25 * 白 + 0.75 * 緑)。
そして、私が得るのは無地の白いテクスチャです...
色をブレンドしないとレンダー ターゲットのアルファ ブレンディング計算が機能しなくなるのはなぜですか? 私の目標は、テクスチャの色を取得せずに、アルファ シャネルの計算のみを行うことです。どうやってやるの ?
ありがとう