Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Stencil sin stencil buffer?

Iniciado por agedito, 25 de Septiembre de 2009, 01:15:09 PM

« anterior - próximo »

agedito

Hola a todos, independientemente de la anterior pregunta sobre estencil...

¿Hay alguna eficiente de conseguir el mismo efecto que un sencil buffer sin usar estos?

Lo que quiero conseguir es mezclar dos imágnes según una máscara en blanco y negro.

Gracias de antemano

blau

#1
Claro, con shaders, pero te adelanto que tiene su intringulis.

Yo lo hago con este codigo, se puede simplificar bastante si sprite que quieres enmascarar es del mismo tamaño que las mascara
En el siguiente caso, tengo varios sprites en una textura, por eso hago toda esa conversion parapoder acceder a las coordenadas de la mascara.


        public override void Draw(GameTime gameTime)
        {
            if (Escena == null) return;

            spriteBatch.Begin();
            {
                spriteBatch.Draw(Escena.Texturas[Escena.Tags.Fondo], ViewportsImperio.Viewport, Color.White);
            }
            spriteBatch.End();

            foreach (SpriteAnimado sprite in Sprites)
            {
                if (sprite.Frames != null)
                {
                    Texture2D mask = Escena.Texturas[Escena.Tags.MascaraVisible];
                    GraphicsDevice.Textures[1] = mask;
                    spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None);
                    {

                        effect.Parameters["TexSpriteSize"].SetValue(new Vector2(sprite.Frame.Textura.Width, sprite.Frame.Textura.Height));
                        effect.Parameters["SourcePos"].SetValue(new Vector2(sprite.Frame.Source.X, sprite.Frame.Source.Y));
                        effect.Parameters["SourceSize"].SetValue(new Vector2(sprite.Frame.Source.Width, sprite.Frame.Source.Height));
                        effect.Parameters["TexMaskSize"].SetValue(new Vector2(mask.Width, mask.Height));

                        Vector2 DestinoPos = ViewportsImperio.PosFromClientToWorld(sprite.Location);
                       
                        effect.Parameters["DestinoPos"].SetValue(DestinoPos);

                        Vector2 DestinoSize = ViewportsImperio.OffsetFromClientToWorld(new Point(sprite.Destino.Width, sprite.Destino.Height));

                        effect.Parameters["DestinoSize"].SetValue(DestinoSize);

                        effect.Begin();
                        {
                            effect.CurrentTechnique.Passes[0].Begin();
                            {
                                spriteBatch.Draw(sprite.Frame.Textura, sprite.Destino, sprite.Frame.Source, Color.White);
                            }
                            effect.CurrentTechnique.Passes[0].End();
                        }
                        effect.End();
                    }
                    spriteBatch.End();
              }
     }


Y el shader:


Color = tex2D(TexSprite, Tex.xy);
   
float2 Ratio = Tex.xy - SourcePos.xy / TexSpriteSize.xy;

Ratio *= TexSpriteSize / SourceSize;

float2 MaskTexPos = Ratio * DestinoSize + DestinoPos;

alpha = tex2D(TexMask, MaskTexPos.xy).a;

Color.a = 1 -alpha;


La idea basica es que en el shader recibes las coordenadas del sprite que quieres enmascarar en spacio screen y asociadas a la textura de tu sprite, y tienes que conseguir las coordenadas en el espacio de la mascara de la textura. para comprobar si el pixel se enmascara o no.

Espero que te sirva de ayuda....  ;)

agedito

Ey,, muchas gracias. VOy a probarlo

P.D: Perdón por tardar tanto en la respuesta

Marci







Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.