2010-04-17 15 views
8

Lo que estoy tratando de hacer es usar la mezcla alfa en XNA para hacer parte de una textura transparente dibujado. Entonces, por ejemplo, borro la pantalla de algún color, digamos Azul. Luego dibujo una textura que es roja. Finalmente dibujo una textura que es solo un degradado radial, desde completamente transparente en el centro hasta completamente negro en el borde. Lo que quiero es que la textura roja dibujada antes sea transparente en los mismos lugares que la textura radial del degradado. Entonces debería poder ver el fondo azul a través de la textura roja.XNA Fundido alfa para hacer parte de una textura transparente

pensé que esto iba a funcionar.

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; 

Pero parece que ignora todas las configuraciones de mi RenderState. También intenté configurar el SpriteBlendMode en AlphaBlend. Combina las texturas, pero ese no es el efecto que quiero.

Cualquier ayuda sería apreciada.

Respuesta

6

Lo que estás tratando de hacer es enmascarar el canal alfa. La manera más fácil es hornear el canal alfa usando la canalización de contenido. Pero si por alguna razón se quiere hacerlo en tiempo de ejecución aquí está la manera (más o menos) usando un objetivo render (Una solución mejor y más rápido sería escribir un shader)

En primer lugar crear un RenderTarget2D para almacenar y textura enmascarada intermedia

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

Ajuste el renderTarget, y estado del dispositivo

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

Ajuste los canales escribir en el R, G, canales B y dibujar la primera textura utilizando un lote de sprites

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

Establecer canales alpha a solamente, y dibujar la máscara alfa

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

ahora puede restaurar el objetivo de rendir a la memoria intermedia hacia atrás y llamar su textura mediante la mezcla alfa.

maskedTexture = shadowRenderTarget.GetTexture(); 
... 

Tampoco se olvide de restaurar el estado:

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

Gracias por la respuesta y esto es extremadamente estrecha, pero su es un problema. La textura del círculo es más pequeña que la textura de fondo, y lo que está sucediendo con el código anterior es que el fondo solo se dibuja donde existe la textura del círculo. La idea es dibujar la textura del círculo donde está el puntero del mouse y el usuario puede ver a través del fondo donde está la textura del círculo. – DangerMouse

+0

@ David, si usted necesita para invertir la máscara alfa borrar el canal alfa utilizando blanco y dibujar el círculo usando negro. –

+0

Funcionó gracias. Tuve que agregar GraphicsDevice.RenderState.DestinationBlend = Blend.Zero; GraphicsDevice.RenderState.SourceBlend = Blend.One; justo antes de dibujar los círculos para conseguir que funcione sin embargo. Pensé que estos eran los valores predeterminados, pero no funcionó hasta que los configuré. Gracias por toda la ayuda. – DangerMouse

Cuestiones relacionadas