2010-10-03 7 views
7

Si utilizo el siguiente¿Hay un valor alfa que hace que el blanco se vuelva invisible?

for(int i = 255; i > 0; i--) 
{ 
    Color transparentBlack = new Color(0, 0, 0, i); 
} 

tengo el efecto del objeto usando este color para dibujar con ir de negro a un gris claro y luego invisible cuando el valor alfa tiende a cero. Sin embargo si comienzo con un valor de blanco:

new Color(255, 255, 255, i); 

Los objetos nunca se vuelve invisible y sólo se queda en blanco. También he notado que si uso un valor que es un poco más claro que el negro (digamos 50, 50, 50) el dibujo va de Oscuro, a invisible, a Blanco.

Supongo que simplemente no entiendo cómo funciona la mezcla alfa de mezcla, pero ¿hay alguna manera de hacer que el color blanco se desvanezca a la translucidez?

Editar: El fondo estoy dibujando en es Color.CornflowerBlue (100149237255)

Editar: Muestra el programa XNA reproducir la explicación. Usar; crear un nuevo proyecto XNA Game Studio 4.0 - Windows juego (4.0), lo llaman AlphaBlendTest - & En el proyecto contenido de añadir un nuevo SpriteFont y llamarlo TestFont

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Audio; 
using Microsoft.Xna.Framework.Content; 
using Microsoft.Xna.Framework.GamerServices; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework.Input; 
using Microsoft.Xna.Framework.Media; 

namespace AlphaBlendTest 
{ 
    /// <summary> 
    /// This is the main type for your game 
    /// </summary> 
    public class Game1 : Microsoft.Xna.Framework.Game 
    { 
     GraphicsDeviceManager graphics; 
     SpriteBatch spriteBatch; 


    SpriteFont font; 

    public Game1() 
    { 
     graphics = new GraphicsDeviceManager(this); 
     Content.RootDirectory = "Content"; 
    } 

    /// <summary> 
    /// Allows the game to perform any initialization it needs to before starting to run. 
    /// This is where it can query for any required services and load any non-graphic 
    /// related content. Calling base.Initialize will enumerate through any components 
    /// and initialize them as well. 
    /// </summary> 
    protected override void Initialize() 
    { 
     // TODO: Add your initialization logic here 

     base.Initialize(); 
    } 

    /// <summary> 
    /// LoadContent will be called once per game and is the place to load 
    /// all of your content. 
    /// </summary> 
    protected override void LoadContent() 
    { 
     // Create a new SpriteBatch, which can be used to draw textures. 
     spriteBatch = new SpriteBatch(GraphicsDevice); 

     font = Content.Load<SpriteFont>("testfont"); 
    } 

    /// <summary> 
    /// UnloadContent will be called once per game and is the place to unload 
    /// all content. 
    /// </summary> 
    protected override void UnloadContent() 
    { 
     // TODO: Unload any non ContentManager content here 
    } 

    /// <summary> 
    /// Allows the game to run logic such as updating the world, 
    /// checking for collisions, gathering input, and playing audio. 
    /// </summary> 
    /// <param name="gameTime">Provides a snapshot of timing values.</param> 
    protected override void Update(GameTime gameTime) 
    { 
     // Allows the game to exit 
     if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) 
      this.Exit(); 

     // TODO: Add your update logic here 

     base.Update(gameTime); 
    } 

    /// <summary> 
    /// This is called when the game should draw itself. 
    /// </summary> 
    /// <param name="gameTime">Provides a snapshot of timing values.</param> 
    protected override void Draw(GameTime gameTime) 
    { 
     GraphicsDevice.Clear(Color.CornflowerBlue); 
     spriteBatch.Begin(); 

     //spriteBatch.Draw(tR, new Rectangle(100, 100, 100, 100), Color.Red); 

     Vector2 v2 = new Vector2(0, 0); 
     spriteBatch.DrawString(font, "Test - White", v2, Color.White); 

     v2.Y = v2.Y + 50; 

     spriteBatch.DrawString(font, "Test - Black", v2, Color.Black); 

     v2.Y = v2.Y + 50; 

     Color BlackTransparent = new Color(0, 0, 0, 0); 
     spriteBatch.DrawString(font, "Test - Black Transparent", v2, BlackTransparent); 

     v2.Y = v2.Y + 50; 
     Color WhiteTransparent = new Color(255, 255, 255, 0); 
     spriteBatch.DrawString(font, "Test - White Transparent", v2, WhiteTransparent); 

     spriteBatch.End(); 

     base.Draw(gameTime); 
    } 
} 
} 

Editar: Esta es la imagen de este código dibuja: alt text

Editar: A uno de los comentarios le preocupa que se trate de una "característica" de Windows relacionada con el texto. Usé el texto como un ejemplo para mantener el programa de demostración pequeño; probar con una imagen da el mismo resultado. alt text

Para añadir la caja cuadrada en la que el programa de demostración; cree una imagen PNG cuadrada en blanco y agréguela al directorio de contenido (use los valores predeterminados para la canalización de contenido). A continuación, añadir esto a la clase:

Texture2D tWhiteBox; 

Añadir esto en el método de carga:

tWhiteBox = Content.Load<Texture2D>("whitebox"); 

Luego, en el sorteo, agregue el siguiente debajo de las otras declaraciones de sorteo:

v2.Y = v2.Y + 50; 
spriteBatch.Draw(tWhiteBox, v2, WhiteTransparent); 
+0

Ahora que tienes mejores respuestas, estoy tentado de eliminar las mías ... pero solo para comprobar, ¿esto sucede con objetos * que no sean de texto * también? –

+0

Sí; Acabo de utilizar Draw String en el ejemplo para no tener que cargar una textura para el programa de prueba simple ;-) Para probar esto, utilicé una imagen que es solo un cuadro blanco y luego la dibujé, usando los diferentes colores en la declaración de dibujo cambiará su color. –

Respuesta

11

Gris es lo que obtendrá en XNA 4.0 (o blanco completo si intenta ajustar el canal alfa sin ajustar también los canales RGB). La transparencia se realiza (por defecto) usando alfa pre-multiplicado. Si está buscando el antiguo comportamiento XNA 3.1 no pre-mul, consulte esta publicación de Shawn Hargreaves: http://blogs.msdn.com/b/shawnhar/archive/2010/04/08/premultiplied-alpha-in-xna-game-studio-4-0.aspx. En la parte inferior de la publicación, te dice cómo hacerlo.

Recomiendo leer todas sus publicaciones en alpha pre-multiplicado antes de hacerlo (puede usar el enlace "Blog Index" en el lado izquierdo cerca de la parte superior de su página) - pre-mul realmente es mucho mejor y mucho más lógicamente consistente.

+2

Gracias, esa publicación tenía la respuesta. Si reemplazo el código que estoy usando con esto: WhiteTransparent = Color.White * 0.5f; Obtengo una imagen blanca transparente al 50%. 0f totalmente transparente y 1f completamente blanco. Desde la publicación, Shawn indica que el código para definir los colores de transparencia ha cambiado y que el código anterior arroja un error de compilación; sin embargo, no se genera ningún error de compilación al definir el valor alfa con el resto del color, según el código con el que tuve un problema. Gracias por tu ayuda. –

+0

Gracias @SebastianGray por deletrearlo. –

0

Si el negro se vuelve "gris claro" cuando es medio transparente, lo que sugiere que tiene un fondo blanco ... en ese punto, un blanco completamente transparente que se pondrá en la parte superior seguirá siendo blanco.

Trate de usar su objeto blanco contra un fondo de otro color, rojo, digamos, que debería pasar de blanco (alfa = 255) a rosa (alfa = 127) a rojo (alfa = 0).

+0

Para probar el fondo del que estoy recurriendo es Color.CornflowerBlue (100,149,237,255). Estoy intentando que funcione algo que pueda usar en un fondo multicolor. –

+0

También probé sobre un fondo rojo y usé un valor de color fijo de Color (255, 255, 255, 0); El color para el objeto que se dibuja era blanco. –

+0

@Sebastian: Hubiera esperado * que estuviera bien entonces. ¿Podría proporcionar un programa de prueba breve pero completo para que podamos verificar que no haya nada más? Si pudieras probarlo primero en una API más fácil de probar (por ejemplo, WPF), eso sería útil también ... aunque entiendo que obviamente también tendremos que hacerlo funcionar en WP7. –

2

Esto es una limitación histórica, al menos en Windows. Las primitivas GDI, como DrawTextEx no son compatibles con la transparencia. Simplemente ignorarán el canal alfa. Esta restricción se resuelve mediante bibliotecas gráficas como GDI + y Milcore. Pero solo hay un renderizador TrueType y hace un trabajo muy poco trivial para ser reemplazado fácilmente. La captura de pantalla muestra que se ejecuta dentro de una ventana de Windows normal, por lo que es muy probable que la restricción se aplique. No estoy seguro de si esto es diferente en una consola.

Una posible solución consiste en utilizar una función similar a GraphicsPath.AddString(). Sin embargo, perderá el efecto anti-aliasing ClearType. No estoy tan seguro de que eso importe en XNA.Tampoco lo sé lo suficientemente bien como para sugerir el equivalente de GraphicsPath.

+0

No creo que la limitación a la que se refiere esté presente en XNA. Agregué una captura de pantalla actualizada y el código para la prueba para usar una imagen también. Originalmente noté este comportamiento en una imagen, pero un ejemplo de texto es el proyecto de demostración más pequeño que pude unir rápidamente, gracias de todos modos. –

1

Creo que tiene algo que ver con la configuración de sangrado de Alpha para SpriteBatch.

El valor predeterminado es BlendState.AplhaBlend. Eso tiene la fórmula BackgroundColor * (1-Alpha) + ForegroundColor. Esto explicaría diferentes comportamientos con blanco y negro.

Pruebe usar el método diferente spriteBatch.Begin con BlendState.NonPremultiplied para obtener el resultado deseado. Esto dará como resultado: BackgroundColor * (1-Alpha) + ForegroundColor * Aplha, haciendo que incluso el blanco sea completamente transparente.

+0

Al iniciar spriteBatch.Draw con BlendState.NonPremultiplied, los sprites se vuelven completamente invisibles con el canal alfa establecido en 255. –

Cuestiones relacionadas