2010-04-17 5 views
8

Quello che sto cercando di fare è usare la fusione alfa in XNA per rendere trasparente una parte di una trama disegnata. Quindi, ad esempio, ho cancellato lo schermo con un po 'di colore, diciamo Blue. Poi disegno una trama che è rossa. Alla fine disegno una texture che è solo un gradiente radiale da completamente trasparente al centro a completamente nero sul bordo. Quello che voglio è che la texture rossa disegnata in precedenza sia trasparente negli stessi punti della trama gradiente radiale. Quindi dovresti essere in grado di vedere il terreno posteriore blu attraverso la trama rossa.XNA Alpha Fusione per rendere trasparente una parte di una trama

Ho pensato che questo avrebbe funzionato.

GraphicsDevice.Clear(Color.CornflowerBlue); 

spriteBatch.Begin(SpriteBlendMode.None); 
spriteBatch.Draw(bg, new Vector2(0, 0), Color.White); 
spriteBatch.End(); 

spriteBatch.Begin(SpriteBlendMode.None); 

GraphicsDevice.RenderState.AlphaBlendEnable = true; 
GraphicsDevice.RenderState.AlphaSourceBlend = Blend.One; 
GraphicsDevice.RenderState.AlphaDestinationBlend = Blend.Zero; 
GraphicsDevice.RenderState.SourceBlend = Blend.Zero; 
GraphicsDevice.RenderState.DestinationBlend = Blend.One; 
GraphicsDevice.RenderState.BlendFunction = BlendFunction.Add; 

spriteBatch.Draw(circle, new Vector2(0, 0), Color.White); 
spriteBatch.End(); 

GraphicsDevice.RenderState.AlphaBlendEnable = false; 

Ma sembra proprio ignorare tutte le mie impostazioni RenderState. Ho anche provato a impostare SpriteBlendMode su AlphaBlend. Mescola le trame, ma questo non è l'effetto che voglio.

Qualsiasi aiuto sarebbe apprezzato.

risposta

6

Quello che stai cercando è mascherare il canale alfa. Il modo più semplice è quello di cuocere il canale alfa usando la pipeline del contenuto. Ma se per qualche motivo si vuole farlo in fase di esecuzione ecco come (circa) utilizzando un target render (Una soluzione migliore e più veloce sarebbe quella di scrivere uno shader)

Innanzitutto creare una RenderTarget2D per memorizzare e consistenza mascherato intermedia

RenderTarget2D maskRenderTarget = GfxComponent.CreateRenderTarget(GraphicsDevice, 
    1, SurfaceFormat.Single); 

Impostare renderTarget, e lo stato del dispositivo

GraphicsDevice.SetRenderTarget(0, maskRenderTarget); 
GraphicsDevice.RenderState.AlphaBlendEnable = true; 
GraphicsDevice.RenderState.DestinationBlend = Blend.Zero; 
GraphicsDevice.RenderState.SourceBlend = Blend.One; 

Impostare i canali per scrivere sulle R, G, B canali e disegnare la prima trama utilizzando un lotto sprite

GraphicsDevice.RenderState.ColorWriteChannels = ColorWriteChannels.Red | ColorWriteChannels.Green | ColorWriteChannels.Blue; 
spriteBatch.Draw(bg, new Vector2(0, 0), Color.White); 

impostare i canali per alpha solo, e disegnare maschera alfa

GraphicsDevice.RenderState.ColorWriteChannels = ColorWriteChannels.Alpha; 
spriteBatch.Draw(circle, new Vector2(0, 0), Color.White); 

ora è possibile ripristinare il target di rendering al buffer posteriore e disegnare la texture con alpha blending.

maskedTexture = shadowRenderTarget.GetTexture(); 
... 

Inoltre, non dimenticare di ripristinare lo stato:

GraphicsDevice.RenderState.ColorWriteChannels = ColorWriteChannels.All; 
... 
+0

Grazie per la risposta e questo è estremamente vicino, ma il loro è un problema. La trama del cerchio è più piccola della trama dello sfondo e ciò che sta accadendo con il codice precedente è che lo sfondo è disegnato solo dove esiste la trama del cerchio. L'idea è di disegnare la trama del cerchio dove si trova il puntatore del mouse e l'utente può vedere attraverso il terreno posteriore dove si trova la trama del cerchio. – DangerMouse

+0

@David, Se è necessario invertire la maschera alfa, deselezionare il canale alfa usando il bianco e disegnare il cerchio usando il nero. –

+0

Ha funzionato grazie. Ho dovuto aggiungere GraphicsDevice.RenderState.DestinationBlend = Blend.Zero; GraphicsDevice.RenderState.SourceBlend = Blend.One; giusto prima di disegnare i cerchi per farlo funzionare. Pensavo che fossero i valori predefiniti ma non ha funzionato fino a quando non li ho impostati. Grazie per tutto l'aiuto. – DangerMouse