Ich versuche, den folgenden Effekt in XNA 4.0 zu erzielen:
Der violette Bereich hat eine Deckkraft von 50%. Ich bin mit dem folgenden Code ziemlich nahe gekommen:
public static DepthStencilState AlwaysStencilState = new DepthStencilState()
{
StencilEnable = true,
StencilFunction = CompareFunction.Always,
StencilPass = StencilOperation.Replace,
ReferenceStencil = 1,
DepthBufferEnable = false,
};
public static DepthStencilState EqualStencilState = new DepthStencilState()
{
StencilEnable = true,
StencilFunction = CompareFunction.Equal,
StencilPass = StencilOperation.Keep,
ReferenceStencil = 1,
DepthBufferEnable = false,
};
...
if (_alphaEffect == null)
{
_alphaEffect = new AlphaTestEffect(_spriteBatch.GraphicsDevice);
_alphaEffect.AlphaFunction = CompareFunction.LessEqual;
_alphaEffect.ReferenceAlpha = 129;
Matrix projection = Matrix.CreateOrthographicOffCenter(0, _spriteBatch.GraphicsDevice.PresentationParameters.BackBufferWidth, _spriteBatch.GraphicsDevice.PresentationParameters.BackBufferHeight, 0, 0, 1);
_alphaEffect.Projection = world.SystemManager.GetSystem<RenderSystem>().Camera.View * projection;
}
_mask = new RenderTarget2D(_spriteBatch.GraphicsDevice, _spriteBatch.GraphicsDevice.PresentationParameters.BackBufferWidth, _spriteBatch.GraphicsDevice.PresentationParameters.BackBufferHeight, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8);
_spriteBatch.GraphicsDevice.SetRenderTarget(_mask);
_spriteBatch.GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.Stencil, Color.Transparent, 0, 0);
_spriteBatch.Begin(SpriteSortMode.Immediate, null, null, AlwaysStencilState, null, _alphaEffect);
_spriteBatch.Draw(sprite.Texture, position, sprite.SourceRectangle,Color.White, 0f, sprite.Origin, 1f, SpriteEffects.None, 0);
_spriteBatch.End();
_spriteBatch.Begin(SpriteSortMode.Immediate, null, null, EqualStencilState, null, null);
_spriteBatch.Draw(_maskTex, new Vector2(x * _maskTex.Width, y * _maskTex.Height), null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0);
_spriteBatch.End();
_spriteBatch.GraphicsDevice.SetRenderTarget(null);
_spriteBatch.GraphicsDevice.Clear(Color.Black);
_spriteBatch.Begin();
_spriteBatch.Draw((Texture2D)_mask, Vector2.Zero, null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, layer/max_layer);
_spriteBatch.End();
Mein Problem ist, dass ich den AlphaTestEffect nicht zum Verhalten bringen kann. Ich kann entweder den halbtransparenten lila Müll maskieren und ihn mit dem grünen Design füllen, oder ich kann über die vollständig undurchsichtige grasartige Textur zeichnen. Wie kann ich die genaue Deckkraft angeben, die durch das grüne Design ersetzt werden muss?
Antworten:
Ich bin mir nicht sicher, ob Sie dies mit dem AlphaTestEffect tun können (tatsächlich weiß ich nicht, wie ATE funktioniert). Ich möchte kürzlich eine Art Menü zeichnen, das den Schablonenpuffer korrekt ausfüllt und eine Art Maske ist.
Mein PixelShader sieht folgendermaßen aus:
AlphaClipValue definiert, welche Pixel in der Textur sichtbar sind. Beispiel: 0.8f definiert, dass alle Alpha-Werte in der Textur, die über 204 liegen, gezeichnet werden. Andere Pixel werden abgeschnitten.
Nun die Auslosung ()
Ich benutze meine eigenen projizierten Quads, um die Textur zu zeichnen, weil mir SpriteBatch nicht gefällt (es setzt einen Zustand zurück, der nicht zurückgesetzt wird). Aber ich denke, es sollte auch mit SpriteBatch funktionieren. Andernfalls können Sie hier nachsehen , wie Sie sie erstellen.
quelle